package cn.wapache.timed.zookeeper;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.ACL;
import org.apache.zookeeper.data.Stat;

import cn.wapache.timed.serialization.JdkSerializer;
import cn.wapache.timed.serialization.SerializeException;
import cn.wapache.timed.serialization.Serializer;

/**
 * 
 * 可以给这个工具类写一个对应的builder类, 这样用起来就更方便了。
 * 
 * @author ykuang
 *
 */
public class ZooKeepers {

	private static final byte[] EMPTY_BYTES={};

	///////////////////////////////////////////////////////////////////////////
	// 连接异常策略
	///////////////////////////////////////////////////////////////////////////
	
	public enum NoAuthStrategy {
		Default, Ignore;
	}
	public enum AuthFailedStrategy {
		Default, Ignore;
	}
	public enum SessionExpiredStrategy {
		Default, Ignore;
	}
	public enum ConnectionLossStrategy {
		Default, Ignore, RetryOne, RetryAlways;
	}
	public enum InterruptedStrategy {
		Default, Ignore, RetryOne, RetryAlways;
	}

	///////////////////////////////////////////////////////////////////////////
	// 操作失败策略
	///////////////////////////////////////////////////////////////////////////
	
	/** 创建策略, 默认/忽略/覆盖数据/删除重建/自动创建祖先节点 */
	public enum CreateStrategy {
		// Default: throw exceptions
		// Ignore: only return result, success or fail
		// 
		Default, Ignore, Override, DeleteAndRecreate, CreateRecursively;
	}
	
	// DeleteRecursively最好还是这样用:
	// DeleteRecursively,DeleteAnyway
	// 因为如果DeleteRecursively删完子节点, 删不掉自己就搞笑了...
	// 
	public enum DeleteStrategy {
		Default, Ignore, DeleteAnyway, DeleteRecursively;
	}
	
	public enum GetDataStrategy {
		Default, ReturnNull, ReturnEmptyArray;
	}

	public enum SetDataStrategy {
		Default, Ignore, UpdateAnyway, CreateIfNotExists, CreateRecursively;
	}
	
	public enum GetChildrenStrategy {
		Default, ReturnNull, ReturnEmptyList;
	}

	///////////////////////////////////////////////////////////////////////////
	// 属性
	///////////////////////////////////////////////////////////////////////////
	
	ZooKeeper zooKeeper;

	// 默认 不可修复异常处理策略
	NoAuthStrategy noAuthStrategy = NoAuthStrategy.Default;
	AuthFailedStrategy authFailedStrategy = AuthFailedStrategy.Default;
	SessionExpiredStrategy sessionExpiredStrategy = SessionExpiredStrategy.Default;
	
	// 默认 可修复异常处理策略
	InterruptedStrategy interruptedStrategy = InterruptedStrategy.RetryAlways;
	ConnectionLossStrategy connectionLossStrategy = ConnectionLossStrategy.RetryAlways;
	
	
	GetDataStrategy getDataStrategy = GetDataStrategy.ReturnEmptyArray;
	GetChildrenStrategy getChildrenStrategy = GetChildrenStrategy.ReturnEmptyList;
	
	Serializer serializer = new JdkSerializer();
	
	List<ACL> acls = Ids.OPEN_ACL_UNSAFE;
	CreateMode createMode = CreateMode.PERSISTENT;
	CreateStrategy[] createStrategies = {CreateStrategy.Default};
	
	///////////////////////////////////////////////////////////////////////////
	// instance methods
	///////////////////////////////////////////////////////////////////////////

	public void setZooKeeper(ZooKeeper zooKeeper) {
		this.zooKeeper = zooKeeper;
	}
	
	/////////////////////////////////////////////////////////////////
	// 分布式序列生成器
	/////////////////////////////////////////////////////////////////
	
	public long getAndAdd(String path, int step){
		return getAndAdd(zooKeeper, path, step,
			noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
			connectionLossStrategy, interruptedStrategy,
			getDataStrategy);
	}
	
	public long getAndAddWithRetry(String path, int step, int retryCount) {
		return getAndAddWithRetry(zooKeeper, path, step,retryCount,
			noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
			connectionLossStrategy, interruptedStrategy,
			getDataStrategy);
	}
	
	// timeout单位毫秒
	public long getAndAddWithTimeout(String path, int step, int timeout) {
		return getAndAddWithTimeout(zooKeeper, path, step,timeout,
			noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
			connectionLossStrategy, interruptedStrategy,
			getDataStrategy);
	}

	public long getAndAdd(String path, int step,
		GetDataStrategy getDataStrategy, SetDataStrategy... setDataStrategies) 
	{
		return getAndAdd(zooKeeper, path, step,
			noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
			connectionLossStrategy, interruptedStrategy,
			getDataStrategy, setDataStrategies);
	}
	
	public long getAndAdd(String path, int step,
		ConnectionLossStrategy connectionLossStrategy, InterruptedStrategy interruptedStrategy,
		GetDataStrategy getDataStrategy, SetDataStrategy... setDataStrategies) 
	{
		return getAndAdd(zooKeeper, path, step,
			noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
			connectionLossStrategy, interruptedStrategy,
			getDataStrategy, setDataStrategies);
	}
	
	public long getAndAdd(String path, int step,
		NoAuthStrategy noAuthStrategy, AuthFailedStrategy authFailedStrategy, SessionExpiredStrategy sessionExpiredStrategy, 
		ConnectionLossStrategy connectionLossStrategy, InterruptedStrategy interruptedStrategy,
		GetDataStrategy getDataStrategy, SetDataStrategy... setDataStrategies) 
	{
		return getAndAdd(zooKeeper, path, step,
			noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
			connectionLossStrategy, interruptedStrategy,
			getDataStrategy, setDataStrategies);
	}
	
	
	/////////////////////////////////////////////////////////////////
	// exists methods, 
	/////////////////////////////////////////////////////////////////

	// 跟`ZooKeeper`的方法一致, 并提供默认的异常处理策略
	
	public boolean exists(String path){
		return exists(zooKeeper,path,false,
			noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
			connectionLossStrategy,interruptedStrategy
		);
	}
	public boolean exists(String path, boolean watch){
		return exists(zooKeeper,path,watch,
			noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
			connectionLossStrategy,interruptedStrategy
		);
	}
	public boolean exists(String path, Watcher watcher){
		return exists(zooKeeper,path,watcher,
			noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
			connectionLossStrategy,interruptedStrategy
		);
	}

	// `不可修复异常`使用默认策略, 可修复异常处理策略通过参数指定

	public boolean exists(String path, boolean watch, 
		ConnectionLossStrategy connectionLossStrategy, InterruptedStrategy interruptedStrategy) 
	{
		return null != getStat(zooKeeper,path,watch,
			noAuthStrategy,authFailedStrategy,sessionExpiredStrategy,
			connectionLossStrategy,interruptedStrategy);
	}
	public boolean exists(String path, Watcher watcher, 
		ConnectionLossStrategy connectionLossStrategy, InterruptedStrategy interruptedStrategy) 
	{
		return null != getStat(zooKeeper,path,watcher,
				noAuthStrategy,authFailedStrategy,sessionExpiredStrategy,
				connectionLossStrategy,interruptedStrategy);
	}

	// 处理策略全部通过参数指定
	
	public boolean exists(String path, boolean watch, 
		NoAuthStrategy noAuthStrategy, AuthFailedStrategy authFailedStrategy, SessionExpiredStrategy sessionExpiredStrategy, 
		ConnectionLossStrategy connectionLossStrategy, InterruptedStrategy interruptedStrategy) 
	{
		return null != getStat(zooKeeper,path,watch,
			noAuthStrategy,authFailedStrategy,sessionExpiredStrategy,
			connectionLossStrategy,interruptedStrategy);
	}
	public boolean exists(String path, Watcher watcher, 
			NoAuthStrategy noAuthStrategy, AuthFailedStrategy authFailedStrategy, SessionExpiredStrategy sessionExpiredStrategy, 
			ConnectionLossStrategy connectionLossStrategy, InterruptedStrategy interruptedStrategy) 
	{
		return null != getStat(zooKeeper,path,watcher,
				noAuthStrategy,authFailedStrategy,sessionExpiredStrategy,
				connectionLossStrategy,interruptedStrategy);
	}


	/////////////////////////////////////////////////////////////////
	// not exists methods
	/////////////////////////////////////////////////////////////////

	// 跟`ZooKeeper`的方法一致, 并提供默认的异常处理策略
	
	public boolean notExists(String path){
		return notExists(zooKeeper,path,false,
			noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
			connectionLossStrategy,interruptedStrategy
		);
	}
	public boolean notExists(String path, boolean watch){
		return notExists(zooKeeper,path,watch,
			noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
			connectionLossStrategy,interruptedStrategy
		);
	}
	public boolean notExists(String path, Watcher watcher){
		return notExists(zooKeeper,path,watcher,
			noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
			connectionLossStrategy,interruptedStrategy
		);
	}

	// `不可修复异常`使用默认策略, 可修复异常处理策略通过参数指定

	public boolean notExists(String path, boolean watch, 
		ConnectionLossStrategy connectionLossStrategy, InterruptedStrategy interruptedStrategy) 
	{
		return null == getStat(zooKeeper,path,watch,
			noAuthStrategy,authFailedStrategy,sessionExpiredStrategy,
			connectionLossStrategy,interruptedStrategy);
	}
	public boolean notExists(String path, Watcher watcher, 
		ConnectionLossStrategy connectionLossStrategy, InterruptedStrategy interruptedStrategy) 
	{
		return null == getStat(zooKeeper,path,watcher,
				noAuthStrategy,authFailedStrategy,sessionExpiredStrategy,
				connectionLossStrategy,interruptedStrategy);
	}

	// 处理策略全部通过参数指定
	
	public boolean notExists(String path, boolean watch, 
		NoAuthStrategy noAuthStrategy, AuthFailedStrategy authFailedStrategy, SessionExpiredStrategy sessionExpiredStrategy, 
		ConnectionLossStrategy connectionLossStrategy, InterruptedStrategy interruptedStrategy) 
	{
		return null == getStat(zooKeeper,path,watch,
			noAuthStrategy,authFailedStrategy,sessionExpiredStrategy,
			connectionLossStrategy,interruptedStrategy);
	}
	public boolean notExists(String path, Watcher watcher, 
			NoAuthStrategy noAuthStrategy, AuthFailedStrategy authFailedStrategy, SessionExpiredStrategy sessionExpiredStrategy, 
			ConnectionLossStrategy connectionLossStrategy, InterruptedStrategy interruptedStrategy) 
	{
		return null == getStat(zooKeeper,path,watcher,
				noAuthStrategy,authFailedStrategy,sessionExpiredStrategy,
				connectionLossStrategy,interruptedStrategy);
	}
	
	/////////////////////////////////////////////////////////////////
	// getStat methods
	/////////////////////////////////////////////////////////////////

	// 跟`ZooKeeper`的方法一致, 并提供默认的异常处理策略
	
	public Stat getStat(String path){
		return getStat(zooKeeper, path, false,
			noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
			connectionLossStrategy, interruptedStrategy
		);
	}
	public Stat getStat(String path, boolean watch){
		return getStat(zooKeeper, path, watch,
			noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
			connectionLossStrategy, interruptedStrategy
		);
	}
	public Stat getStat(String path, Watcher watcher){
		return getStat(zooKeeper, path, watcher,
			noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
			connectionLossStrategy, interruptedStrategy
		);
	}

	// `不可修复异常`使用默认策略, 可修复异常处理策略通过参数指定

	public Stat getStat(String path, boolean watch, 
		ConnectionLossStrategy connectionLossStrategy, InterruptedStrategy interruptedStrategy)
	{
		return getStat(zooKeeper, path, watch,
			noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
			connectionLossStrategy, interruptedStrategy
		);
	}
	public Stat getStat(String path, Watcher watcher, 
		ConnectionLossStrategy connectionLossStrategy, InterruptedStrategy interruptedStrategy)
	{
		return getStat(zooKeeper, path, watcher,
			noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
			connectionLossStrategy, interruptedStrategy
		);
	}

	// 处理策略全部通过参数指定
	
	public Stat getStat(String path, boolean watch, 
		NoAuthStrategy noAuthStrategy, AuthFailedStrategy authFailedStrategy, SessionExpiredStrategy sessionExpiredStrategy, 
		ConnectionLossStrategy connectionLossStrategy, InterruptedStrategy interruptedStrategy)
	{
		return getStat(zooKeeper, path, watch,
			noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
			connectionLossStrategy, interruptedStrategy
		);
	}
	public Stat getStat(String path, Watcher watcher, 
		NoAuthStrategy noAuthStrategy, AuthFailedStrategy authFailedStrategy, SessionExpiredStrategy sessionExpiredStrategy, 
		ConnectionLossStrategy connectionLossStrategy, InterruptedStrategy interruptedStrategy)
	{
		return getStat(zooKeeper, path, watcher,
			noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
			connectionLossStrategy, interruptedStrategy
		);
	}
	
	/////////////////////////////////////////////////////////////////
	// getData  methods
	/////////////////////////////////////////////////////////////////

	// 跟`ZooKeeper`的方法一致, 并提供默认的异常处理策略
	
	public byte[] getData(String path){
		return getData(zooKeeper,path,false,null,
			noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
			connectionLossStrategy, interruptedStrategy, 
			getDataStrategy
		);
	}
	public byte[] getData(String path, Stat stat){
		return getData(zooKeeper,path,false,stat,
				noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
				connectionLossStrategy, interruptedStrategy, 
				getDataStrategy
			);
	}
	public byte[] getData(String path, boolean watch, Stat stat){
		return getData(zooKeeper,path,watch,stat,
			noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
			connectionLossStrategy, interruptedStrategy, 
			getDataStrategy
		);
	}
	public byte[] getData(String path, Watcher watcher, Stat stat){
		return getData(zooKeeper,path,watcher,stat,
			noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
			connectionLossStrategy, interruptedStrategy, 
			getDataStrategy
		);
	}
	
	public byte[] getData(String path, boolean watch, Stat stat, GetDataStrategy getDataStrategy){
		return getData(zooKeeper,path,watch,stat,
			noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
			connectionLossStrategy, interruptedStrategy, 
			getDataStrategy
		);
	}
	public byte[] getData(String path, Watcher watcher, Stat stat, GetDataStrategy getDataStrategy){
		return getData(zooKeeper,path,watcher,stat,
			noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
			connectionLossStrategy, interruptedStrategy, 
			getDataStrategy
		);
	}
	
	// `不可修复异常`使用默认策略, 可修复异常处理策略通过参数指定

	public byte[] getData(String path, boolean watch, Stat stat,
		ConnectionLossStrategy connectionLossStrategy, InterruptedStrategy interruptedStrategy, 
		GetDataStrategy getDataStrategy)
	{
		return getData(zooKeeper,path,watch,stat,
			noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
			connectionLossStrategy, interruptedStrategy, 
			getDataStrategy
		);
	}

	public byte[] getData(String path, Watcher watcher, Stat stat,
		ConnectionLossStrategy connectionLossStrategy, InterruptedStrategy interruptedStrategy, 
		GetDataStrategy getDataStrategy)
	{
		return getData(zooKeeper,path,watcher,stat,
			noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
			connectionLossStrategy, interruptedStrategy, 
			getDataStrategy
		);
	}
	
	// 处理策略全部通过参数指定

	public byte[] getData(String path, boolean watch, Stat stat,
		NoAuthStrategy noAuthStrategy, AuthFailedStrategy authFailedStrategy, SessionExpiredStrategy sessionExpiredStrategy, 
		ConnectionLossStrategy connectionLossStrategy, InterruptedStrategy interruptedStrategy, 
		GetDataStrategy getDataStrategy)
	{
		return getData(zooKeeper,path,watch,stat,
			noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
			connectionLossStrategy, interruptedStrategy, 
			getDataStrategy
		);
	}

	public byte[] getData(String path, Watcher watcher, Stat stat,
		NoAuthStrategy noAuthStrategy, AuthFailedStrategy authFailedStrategy, SessionExpiredStrategy sessionExpiredStrategy, 
		ConnectionLossStrategy connectionLossStrategy, InterruptedStrategy interruptedStrategy, 
		GetDataStrategy getDataStrategy)
	{
		return getData(zooKeeper,path,watcher,stat,
			noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
			connectionLossStrategy, interruptedStrategy, 
			getDataStrategy
		);
	}
	
	/////////////////////////////////////////////////////////////////
	// setData  methods
	/////////////////////////////////////////////////////////////////

	// 跟`ZooKeeper`的方法一致, 并提供默认的异常处理策略
	
	public Stat setData(String path, byte[] data, SetDataStrategy... setDataStrategies) {
		return setData(zooKeeper, path, data, setDataStrategies);
	}
	public Stat setData(String path, byte[] data, int version, SetDataStrategy... setDataStrategies)  {
		return setData(zooKeeper, path, data, version, setDataStrategies);
	}

	// `不可修复异常`使用默认策略, 可修复异常处理策略通过参数指定

	public Stat setData(String path, byte[] data, 
		ConnectionLossStrategy connectionLossStrategy, InterruptedStrategy interruptedStrategy,
		SetDataStrategy... setDataStrategies) 
	{
		return setData(zooKeeper, path, data, -1, 
			noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
			connectionLossStrategy, interruptedStrategy,
			setDataStrategies);
	}
	
	public Stat setData(String path, byte[] data, int version,
		ConnectionLossStrategy connectionLossStrategy, InterruptedStrategy interruptedStrategy,
		SetDataStrategy... setDataStrategies) 
	{
		return setData(zooKeeper, path, data, version, 
			noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
			connectionLossStrategy, interruptedStrategy,
			setDataStrategies);
	}

	// 处理策略全部通过参数指定

	public Stat setData(String path, byte[] data, 
		NoAuthStrategy noAuthStrategy, AuthFailedStrategy authFailedStrategy, SessionExpiredStrategy sessionExpiredStrategy, 
		ConnectionLossStrategy connectionLossStrategy, InterruptedStrategy interruptedStrategy,
		SetDataStrategy... setDataStrategies) 
	{
		return setData(zooKeeper, path, data, -1, 
				noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
				connectionLossStrategy, interruptedStrategy,
				setDataStrategies);
	}
	
	public Stat setData(String path, byte[] data, int version,  
		NoAuthStrategy noAuthStrategy, AuthFailedStrategy authFailedStrategy, SessionExpiredStrategy sessionExpiredStrategy, 
		ConnectionLossStrategy connectionLossStrategy, InterruptedStrategy interruptedStrategy,
		SetDataStrategy... setDataStrategies) 
	{
		return setData(zooKeeper, path, data, version, 
				noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
				connectionLossStrategy, interruptedStrategy,
				setDataStrategies);
	}
	
	/////////////////////////////////////////////////////////////////
	// readXXX  methods
	/////////////////////////////////////////////////////////////////

	// 使用默认的异常处理策略

	public <T> T readObject(String path) {
		return readObject(zooKeeper,path,serializer, null);
	}
	public <T> T readObject(String path, T def) {
		return readObject(zooKeeper,path,serializer, def);
	}

	public <T> T readObject(String path, Serializer serializer) {
		return readObject(zooKeeper,path,serializer,null);
	}
	
	public <T> T readObject(String path, Serializer serializer, T def) {
		return readObject(zooKeeper,path,serializer,def);
	}
	
	public String readString(String path, String def) {
		byte[] data = getData(zooKeeper, path);
		if(data.length==0) {
			return def;
		}else{
			return new String(data);
		}
	}
	
	public String readString(String path, Charset charset, String def) {
		byte[] data = getData(zooKeeper, path);
		if(data.length==0) {
			return def;
		}else{
			return new String(data, charset);
		}
	}
	
	// `不可修复异常`使用默认策略, 可修复异常处理策略通过参数指定

	// 处理策略全部通过参数指定


	/////////////////////////////////////////////////////////////////
	// writeXXX  methods
	/////////////////////////////////////////////////////////////////

	// 跟`ZooKeeper`的方法一致, 并提供默认的异常处理策略
	
	public Stat writeObject(String path, Object obj, SetDataStrategy... setDataStrategies)  {
		return setData(zooKeeper,path,serialize(serializer, obj, setDataStrategies),-1,
			noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
			connectionLossStrategy,interruptedStrategy, 
			setDataStrategies);
	}
	public Stat writeObject(String path, Object obj, int version, SetDataStrategy... setDataStrategies)  {
		return setData(zooKeeper,path,serialize(serializer, obj, setDataStrategies),version,
				noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
				connectionLossStrategy,interruptedStrategy, 
				setDataStrategies);
	}
	public Stat writeObject(String path, Object obj, Serializer serializer, SetDataStrategy... setDataStrategies)  {
		return setData(zooKeeper,path,serialize(serializer, obj, setDataStrategies),-1,
				noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
				connectionLossStrategy,interruptedStrategy, 
				setDataStrategies);
	}
	public Stat writeObject(String path, Object obj, int version, Serializer serializer, SetDataStrategy... setDataStrategies)  {
		return setData(zooKeeper,path,serialize(serializer, obj, setDataStrategies),version,
			noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
			connectionLossStrategy,interruptedStrategy, 
			setDataStrategies);
	}

	public byte[] serialize(Serializer serializer, Object obj, SetDataStrategy... setDataStrategies)  {
		try{
			return serializer.serialize(obj);
        } catch (SerializeException e) {
        	List<SetDataStrategy> list = Arrays.asList(setDataStrategies);
        	if(list.contains(SetDataStrategy.Ignore)){
        		return null;
        	}
			e.printStackTrace();
			throw new SerializeRuntimeException(e);
		}
	}

	// `不可修复异常`使用默认策略, 可修复异常处理策略通过参数指定

	// 处理策略全部通过参数指定
	
	
	/////////////////////////////////////////////////////////////////
	// getChildren  methods
	/////////////////////////////////////////////////////////////////

	// 跟`ZooKeeper`的方法一致, 并提供默认的异常处理策略
	
	public List<String> getChildren(String path) {
		return getChildren(zooKeeper,path,false,null,
			noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
			connectionLossStrategy,interruptedStrategy, 
			getChildrenStrategy);
	}
	public List<String> getChildren(String path, boolean watch, Stat stat) {
		return getChildren(zooKeeper,path,watch,stat,
			noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
			connectionLossStrategy,interruptedStrategy, 
			getChildrenStrategy);
	}
	public List<String> getChildren(String path, Watcher watcher) {
		return getChildren(zooKeeper,path,watcher,null,
				noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
				connectionLossStrategy,interruptedStrategy, 
				getChildrenStrategy);
	}
	public List<String> getChildren(String path, Watcher watcher, Stat stat) {
		return getChildren(zooKeeper,path,watcher,stat,
				noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
				connectionLossStrategy,interruptedStrategy, 
				getChildrenStrategy);
	}

	public List<String> getChildren(String path, GetChildrenStrategy getChildrenStrategy) {
		return getChildren(zooKeeper,path,false,null,
			noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
			connectionLossStrategy,interruptedStrategy, 
			getChildrenStrategy);
	}
	public List<String> getChildren(String path, boolean watch, Stat stat, GetChildrenStrategy getChildrenStrategy) {
		return getChildren(zooKeeper,path,watch,stat,
			noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
			connectionLossStrategy,interruptedStrategy, 
			getChildrenStrategy);
	}
	public List<String> getChildren(String path, Watcher watcher, GetChildrenStrategy getChildrenStrategy) {
		return getChildren(zooKeeper,path,watcher,null,
				noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
				connectionLossStrategy,interruptedStrategy, 
				getChildrenStrategy);
	}
	public List<String> getChildren(String path, Watcher watcher, Stat stat, GetChildrenStrategy getChildrenStrategy) {
		return getChildren(zooKeeper,path,watcher,stat,
				noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
				connectionLossStrategy,interruptedStrategy, 
				getChildrenStrategy);
	}
	
	// `不可修复异常`使用默认策略, 可修复异常处理策略通过参数指定

	public List<String> getChildren(String path, 
		ConnectionLossStrategy connectionLossStrategy, InterruptedStrategy interruptedStrategy, 
		GetChildrenStrategy getChildrenStrategy) 
	{
		return getChildren(zooKeeper,path,false,null,
			noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
			connectionLossStrategy,interruptedStrategy, 
			getChildrenStrategy);
	}
	public List<String> getChildren(String path, boolean watch, 
		ConnectionLossStrategy connectionLossStrategy, InterruptedStrategy interruptedStrategy, 
		GetChildrenStrategy getChildrenStrategy) 
	{
		return getChildren(zooKeeper,path,watch,null,
			noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
			connectionLossStrategy,interruptedStrategy, 
			getChildrenStrategy);
	}

	public List<String> getChildren(String path, boolean watch, Stat stat,
		ConnectionLossStrategy connectionLossStrategy, InterruptedStrategy interruptedStrategy, 
		GetChildrenStrategy getChildrenStrategy) 
	{
		return getChildren(zooKeeper,path,watch,stat,
			noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
			connectionLossStrategy,interruptedStrategy, 
			getChildrenStrategy);
	}
	
	public List<String> getChildren(String path, Watcher watcher,
		ConnectionLossStrategy connectionLossStrategy, InterruptedStrategy interruptedStrategy, 
		GetChildrenStrategy getChildrenStrategy) 
	{
		return getChildren(zooKeeper,path,watcher,null,
			noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
			connectionLossStrategy,interruptedStrategy, 
			getChildrenStrategy);
	}
	
	public List<String> getChildren(String path, Watcher watcher, Stat stat,
		ConnectionLossStrategy connectionLossStrategy, InterruptedStrategy interruptedStrategy, 
		GetChildrenStrategy getChildrenStrategy) 
	{
		return getChildren(zooKeeper,path,watcher,stat,
			noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
			connectionLossStrategy,interruptedStrategy, 
			getChildrenStrategy);
	}
	
	// 处理策略全部通过参数指定

	public List<String> getChildren(String path, 
		NoAuthStrategy noAuthStrategy, AuthFailedStrategy authFailedStrategy, SessionExpiredStrategy sessionExpiredStrategy, 
		ConnectionLossStrategy connectionLossStrategy, InterruptedStrategy interruptedStrategy, 
		GetChildrenStrategy getChildrenStrategy) 
	{
		return getChildren(zooKeeper,path,false,null,
			noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
			connectionLossStrategy,interruptedStrategy, 
			getChildrenStrategy);
	}
	public List<String> getChildren(String path, boolean watch, 
		NoAuthStrategy noAuthStrategy, AuthFailedStrategy authFailedStrategy, SessionExpiredStrategy sessionExpiredStrategy, 
		ConnectionLossStrategy connectionLossStrategy, InterruptedStrategy interruptedStrategy, 
		GetChildrenStrategy getChildrenStrategy) 
	{
		return getChildren(zooKeeper,path,watch,null,
			noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
			connectionLossStrategy,interruptedStrategy, 
			getChildrenStrategy);
	}
	public List<String> getChildren(String path, boolean watch, Stat stat,
		NoAuthStrategy noAuthStrategy, AuthFailedStrategy authFailedStrategy, SessionExpiredStrategy sessionExpiredStrategy, 
		ConnectionLossStrategy connectionLossStrategy, InterruptedStrategy interruptedStrategy, 
		GetChildrenStrategy getChildrenStrategy) 
	{
		return getChildren(zooKeeper,path,watch,stat,
			noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
			connectionLossStrategy,interruptedStrategy, 
			getChildrenStrategy);
	}
	public List<String> getChildren(String path, Watcher watcher,
		NoAuthStrategy noAuthStrategy, AuthFailedStrategy authFailedStrategy, SessionExpiredStrategy sessionExpiredStrategy, 
		ConnectionLossStrategy connectionLossStrategy, InterruptedStrategy interruptedStrategy, 
		GetChildrenStrategy getChildrenStrategy) 
	{
		return getChildren(zooKeeper,path,watcher,null,
			noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
			connectionLossStrategy,interruptedStrategy, 
			getChildrenStrategy);
	}
	public List<String> getChildren(String path, Watcher watcher, Stat stat,
		NoAuthStrategy noAuthStrategy, AuthFailedStrategy authFailedStrategy, SessionExpiredStrategy sessionExpiredStrategy, 
		ConnectionLossStrategy connectionLossStrategy, InterruptedStrategy interruptedStrategy, 
		GetChildrenStrategy getChildrenStrategy) 
	{
		return getChildren(zooKeeper,path,watcher,stat,
			noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
			connectionLossStrategy,interruptedStrategy, 
			getChildrenStrategy);
	}

	/////////////////////////////////////////////////////////////////
	// delete  methods
	/////////////////////////////////////////////////////////////////

	// 跟`ZooKeeper`的方法一致, 并提供默认的异常处理策略
	

	public boolean delete(String path, DeleteStrategy... deleteStrategies ) 
		throws InterruptedRuntimeException, KeeperRuntimeException 
	{
		return delete(zooKeeper,path,-1,
				noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
				connectionLossStrategy,interruptedStrategy, 
				deleteStrategies);
	}
	public boolean delete(String path, int version, DeleteStrategy... deleteStrategies ) 
		throws InterruptedRuntimeException, KeeperRuntimeException 
	{
		return delete(zooKeeper,path,version,
				noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
				connectionLossStrategy,interruptedStrategy, 
				deleteStrategies);
	}

	public boolean deleteRecursively(String path) 
			throws InterruptedRuntimeException, KeeperRuntimeException 
	{
		return delete(zooKeeper,path,-1,
				noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
				connectionLossStrategy,interruptedStrategy, 
				DeleteStrategy.DeleteRecursively);
	}
	public boolean deleteRecursively(String path, int version) 
			throws InterruptedRuntimeException, KeeperRuntimeException 
	{
		return delete(zooKeeper,path,version,
				noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
				connectionLossStrategy,interruptedStrategy, 
				DeleteStrategy.DeleteRecursively);
	}

	// `不可修复异常`使用默认策略, 可修复异常处理策略通过参数指定

	public boolean delete(String path,
		ConnectionLossStrategy connectionLossStrategy, InterruptedStrategy interruptedStrategy,
		DeleteStrategy... deleteStrategies ) 
		throws InterruptedRuntimeException, KeeperRuntimeException 
	{
		return delete(zooKeeper,path,-1,
			noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
			connectionLossStrategy,interruptedStrategy, 
			deleteStrategies);
	}
	public boolean delete(String path, int version,  
		ConnectionLossStrategy connectionLossStrategy, InterruptedStrategy interruptedStrategy,
		DeleteStrategy... deleteStrategies ) 
		throws InterruptedRuntimeException, KeeperRuntimeException 
	{
		return delete(zooKeeper,path,version,
			noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
			connectionLossStrategy,interruptedStrategy, 
			deleteStrategies);
	}

	// 处理策略全部通过参数指定

	public boolean delete(String path, 
		NoAuthStrategy noAuthStrategy, AuthFailedStrategy authFailedStrategy, SessionExpiredStrategy sessionExpiredStrategy, 
		ConnectionLossStrategy connectionLossStrategy, InterruptedStrategy interruptedStrategy,
		DeleteStrategy... deleteStrategies ) 
		throws InterruptedRuntimeException, KeeperRuntimeException 
	{
		return delete(zooKeeper,path,-1,
			noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
			connectionLossStrategy,interruptedStrategy, 
			deleteStrategies);
	}
	public boolean delete(String path, int version,  
		NoAuthStrategy noAuthStrategy, AuthFailedStrategy authFailedStrategy, SessionExpiredStrategy sessionExpiredStrategy, 
		ConnectionLossStrategy connectionLossStrategy, InterruptedStrategy interruptedStrategy,
		DeleteStrategy... deleteStrategies ) 
		throws InterruptedRuntimeException, KeeperRuntimeException 
	{
		return delete(zooKeeper,path,version,
			noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
			connectionLossStrategy,interruptedStrategy, 
			deleteStrategies);
	}
	
	/////////////////////////////////////////////////////////////////
	// create  methods
	/////////////////////////////////////////////////////////////////

	// 跟`ZooKeeper`的方法一致, 并提供默认的异常处理策略

	public boolean create(String path, CreateStrategy... createStrategies) {
		return create(zooKeeper,path,EMPTY_BYTES,acls,createMode,
			noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
			connectionLossStrategy,interruptedStrategy, 
			createStrategies);
	}
	public boolean create(String path, byte[] data, CreateStrategy... createStrategies){
		return create(zooKeeper,path,data,acls,createMode,
				noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
				connectionLossStrategy,interruptedStrategy, 
				createStrategies);
	}
	public boolean create(String path, byte[] data, CreateMode createMode, CreateStrategy... createStrategies){
		return create(zooKeeper,path,data,acls,createMode,
				noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
				connectionLossStrategy,interruptedStrategy, 
				createStrategies);
	}
	public boolean create(String path, byte[] data, List<ACL> acl, CreateStrategy... createStrategies){
		return create(zooKeeper,path,data,acls,createMode,
				noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
				connectionLossStrategy,interruptedStrategy, 
				createStrategies);
	}
	public boolean create(String path, byte[] data, List<ACL> acl, CreateMode createMode, CreateStrategy... createStrategies){
		return create(zooKeeper,path,data,acls,createMode,
				noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
				connectionLossStrategy,interruptedStrategy, 
				createStrategies);
	}

	// 中断及操作失败异常处理策略通过参数指定
	
	public boolean create(String path, byte[] data, InterruptedStrategy interruptedStrategy, CreateStrategy... createStrategies) {
		return create(zooKeeper,path,data,acls,createMode,
				noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
				connectionLossStrategy,interruptedStrategy, 
				createStrategies);
	}
	public boolean create(String path, byte[] data, CreateMode createMode, InterruptedStrategy interruptedStrategy, CreateStrategy... createStrategies) {
		return create(zooKeeper,path,data,acls,createMode,
				noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
				connectionLossStrategy,interruptedStrategy, 
				createStrategies);
	}
	public boolean create(String path, byte[] data, List<ACL> acl, CreateMode createMode, 
		InterruptedStrategy interruptedStrategy, CreateStrategy... createStrategies) 
	{
		return create(zooKeeper,path,data,acls,createMode,
			noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
			connectionLossStrategy,interruptedStrategy, 
			createStrategies);
	}

	// `不可修复异常`使用默认策略, 可修复异常处理策略通过参数指定

	public boolean create(String path, byte[] data, List<ACL> acl, CreateMode createMode, 
		ConnectionLossStrategy connectionLossStrategy, InterruptedStrategy interruptedStrategy, 
		CreateStrategy... createStrategies) 
	{
		return create(zooKeeper,path,data,acls,createMode,
			noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
			connectionLossStrategy,interruptedStrategy, 
			createStrategies);
	}

	// 处理策略全部通过参数指定
	
	public boolean create(String path, byte[] data, List<ACL> acl, CreateMode createMode, 
		NoAuthStrategy noAuthStrategy, AuthFailedStrategy authFailedStrategy, SessionExpiredStrategy sessionExpiredStrategy, 
		ConnectionLossStrategy connectionLossStrategy, InterruptedStrategy interruptedStrategy, 
		CreateStrategy... createStrategies) 
	{
		return create(zooKeeper,path,data,acls,createMode,
			noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
			connectionLossStrategy,interruptedStrategy, 
			createStrategies);
	}
	
	
	public boolean createEphemeralRecursively(String path) {
		return create(zooKeeper,path,EMPTY_BYTES,acls,CreateMode.EPHEMERAL,
			noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
			connectionLossStrategy,interruptedStrategy,
			CreateStrategy.CreateRecursively, CreateStrategy.Ignore);
	}
	public boolean createEphemeralRecursively(String path, byte[] data) {
		return create(zooKeeper,path,data,acls,CreateMode.EPHEMERAL,
			noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
			connectionLossStrategy,interruptedStrategy,
			CreateStrategy.CreateRecursively, CreateStrategy.Ignore);
	}
	public boolean createEphemeral(String path, byte[] data) {
		return create(zooKeeper,path,data,acls,CreateMode.EPHEMERAL,
			noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
			connectionLossStrategy,interruptedStrategy,
			CreateStrategy.Ignore);
	}
	
	/////////////////////////////////////////////////////////////////
	// ???  methods
	/////////////////////////////////////////////////////////////////

	// 跟`ZooKeeper`的方法一致, 并提供默认的异常处理策略

	public boolean createObject(String path, Object obj, CreateStrategy... createStrategies) {
		return create(zooKeeper,path,serialize(serializer, obj,createStrategies),acls,createMode,
			noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
			connectionLossStrategy,interruptedStrategy, 
			createStrategies);
	}
	public boolean createObject(String path, Object obj, Serializer serializer, CreateStrategy... createStrategies)  {
		return create(zooKeeper,path,serialize(serializer, obj,createStrategies),acls,createMode,
			noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
			connectionLossStrategy,interruptedStrategy, 
			createStrategies);
	}
	
	public boolean createEphemeralObject(String path, Object obj, CreateStrategy... createStrategies)  {
		return create(zooKeeper,path,serialize(serializer, obj,createStrategies),acls,CreateMode.EPHEMERAL,
				noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
				connectionLossStrategy,interruptedStrategy, 
				createStrategies);
	}
	public boolean createEphemeralObject(String path, Object obj, Serializer serializer, CreateStrategy... createStrategies) {
		return create(zooKeeper,path,serialize(serializer, obj,createStrategies),acls,CreateMode.EPHEMERAL,
			noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
			connectionLossStrategy,interruptedStrategy, 
			createStrategies);
	}

	// `不可修复异常`使用默认策略, 可修复异常处理策略通过参数指定

	// 处理策略全部通过参数指定
	public boolean createObject(String path, Object obj, List<ACL> acl, CreateMode createMode, 
		NoAuthStrategy noAuthStrategy, AuthFailedStrategy authFailedStrategy, SessionExpiredStrategy sessionExpiredStrategy, 
		ConnectionLossStrategy connectionLossStrategy, InterruptedStrategy interruptedStrategy, 
		CreateStrategy... createStrategies)  
	{
		return create(zooKeeper,path,serialize(serializer, obj,createStrategies),acl,createMode,
			noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
			connectionLossStrategy,interruptedStrategy, 
			createStrategies);
	}
	public boolean createObject(String path, Object obj, List<ACL> acl, CreateMode createMode, Serializer serializer, 
		NoAuthStrategy noAuthStrategy, AuthFailedStrategy authFailedStrategy, SessionExpiredStrategy sessionExpiredStrategy, 
		ConnectionLossStrategy connectionLossStrategy, InterruptedStrategy interruptedStrategy, 
		CreateStrategy... createStrategies)  
	{
		return create(zooKeeper,path,serialize(serializer, obj,createStrategies),acl,createMode,
			noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
			connectionLossStrategy,interruptedStrategy, 
			createStrategies);
	}

	public byte[] serialize(Serializer serializer, Object obj, CreateStrategy... setDataStrategies)  {
		try{
			return serializer.serialize(obj);
        } catch (SerializeException e) {
        	e.printStackTrace();
        	List<CreateStrategy> list = Arrays.asList(setDataStrategies);
        	if(list.contains(CreateStrategy.Ignore)){
        		return null;
        	}
			throw new SerializeRuntimeException(e);
		}
	}
	
	/////////////////////////////////////////////////////////////////
	// ???  methods
	/////////////////////////////////////////////////////////////////

	// 跟`ZooKeeper`的方法一致, 并提供默认的异常处理策略

	// `不可修复异常`使用默认策略, 可修复异常处理策略通过参数指定

	// 处理策略全部通过参数指定
	
	//#########################################################################
	// static methods
	//#########################################################################
	
	
	///////////////////////////////////////////////////////////////////////////
	// 通用
	///////////////////////////////////////////////////////////////////////////
	
//	AUTHFAILED     AuthFailedException - ???
	// 对应策略 1. 向上抛异常 2. 忽略
//	SESSIONEXPIRED SessionExpiredException - 没得救了, 重新建立连接, 重新建立会话吧
	// 对应策略 1. 向上抛异常 2. 忽略
//	CONNECTIONLOSS ConnectionLossException - 等ZooKeeper重新连接再重试
	// 对应策略 1. 向上抛异常 2. 忽略 3. 重试一次 4. 一直重试
//	NOAUTH         NoAuthException         - 没有相应权限	
	// 对应策略 1. 向上抛异常 2. 忽略


///////////////////////////////////////////////////////////////////////////
// exists
///////////////////////////////////////////////////////////////////////////
//ZooKeeper.exists
//
//– exists(String path, boolean watch)
//– exists(String path, Watcher watcher)
	
	public static boolean exists(ZooKeeper zooKeeper, String path) {
		return exists(zooKeeper,path,false,
			NoAuthStrategy.Default, AuthFailedStrategy.Default, SessionExpiredStrategy.Default, 
			ConnectionLossStrategy.Default,InterruptedStrategy.Default
		);
	}
	public static boolean exists(ZooKeeper zooKeeper, String path, boolean watch) {
		return exists(zooKeeper,path,watch,
			NoAuthStrategy.Default, AuthFailedStrategy.Default, SessionExpiredStrategy.Default, 
			ConnectionLossStrategy.Default,InterruptedStrategy.Default
		);
	}
	public static boolean exists(ZooKeeper zooKeeper, String path, Watcher watcher) {
		return exists(zooKeeper,path,watcher,
			NoAuthStrategy.Default, AuthFailedStrategy.Default, SessionExpiredStrategy.Default, 
			ConnectionLossStrategy.Default,InterruptedStrategy.Default
		);
	}
	
	public static boolean exists(ZooKeeper zooKeeper, String path, boolean watch, 
			NoAuthStrategy noAuthStrategy, AuthFailedStrategy authFailedStrategy, SessionExpiredStrategy sessionExpiredStrategy, 
			ConnectionLossStrategy connectionLossStrategy, InterruptedStrategy interruptedStrategy) {
		
		return null != getStat(zooKeeper,path,watch,
				noAuthStrategy,authFailedStrategy,sessionExpiredStrategy,
				connectionLossStrategy,interruptedStrategy);
	}
	public static boolean exists(ZooKeeper zooKeeper, String path, Watcher watcher, 
			NoAuthStrategy noAuthStrategy, AuthFailedStrategy authFailedStrategy, SessionExpiredStrategy sessionExpiredStrategy, 
			ConnectionLossStrategy connectionLossStrategy, InterruptedStrategy interruptedStrategy) {
		
		return null != getStat(zooKeeper,path,watcher,
				noAuthStrategy,authFailedStrategy,sessionExpiredStrategy,
				connectionLossStrategy,interruptedStrategy);
	}

	
	public static boolean notExists(ZooKeeper zooKeeper, String path) {
		return notExists(zooKeeper,path,false,
			NoAuthStrategy.Default, AuthFailedStrategy.Default, SessionExpiredStrategy.Default, 
			ConnectionLossStrategy.Default,InterruptedStrategy.Default
		);
	}
	public static boolean notExists(ZooKeeper zooKeeper, String path, boolean watch) {
		return notExists(zooKeeper,path,watch,
			NoAuthStrategy.Default, AuthFailedStrategy.Default, SessionExpiredStrategy.Default, 
			ConnectionLossStrategy.Default,InterruptedStrategy.Default
		);
	}
	public static boolean notExists(ZooKeeper zooKeeper, String path, Watcher watcher) {
		return notExists(zooKeeper,path,watcher,
			NoAuthStrategy.Default, AuthFailedStrategy.Default, SessionExpiredStrategy.Default, 
			ConnectionLossStrategy.Default,InterruptedStrategy.Default
		);
	}
	
	public static boolean notExists(ZooKeeper zooKeeper, String path, boolean watch, 
			NoAuthStrategy noAuthStrategy, AuthFailedStrategy authFailedStrategy, SessionExpiredStrategy sessionExpiredStrategy, 
			ConnectionLossStrategy connectionLossStrategy, InterruptedStrategy interruptedStrategy) {
		
		return null == getStat(zooKeeper,path,watch,
				noAuthStrategy,authFailedStrategy,sessionExpiredStrategy,
				connectionLossStrategy,interruptedStrategy);
	}
	public static boolean notExists(ZooKeeper zooKeeper, String path, Watcher watcher, 
			NoAuthStrategy noAuthStrategy, AuthFailedStrategy authFailedStrategy, SessionExpiredStrategy sessionExpiredStrategy, 
			ConnectionLossStrategy connectionLossStrategy, InterruptedStrategy interruptedStrategy) {
		
		return null == getStat(zooKeeper,path,watcher,
				noAuthStrategy,authFailedStrategy,sessionExpiredStrategy,
				connectionLossStrategy,interruptedStrategy);
	}
	
	
	
	public static Stat getStat(ZooKeeper zooKeeper, String path) {
		return getStat(zooKeeper,path,false,
			NoAuthStrategy.Default, AuthFailedStrategy.Default, SessionExpiredStrategy.Default, 
			ConnectionLossStrategy.Default,InterruptedStrategy.Default
		);
	}
	
	public static Stat getStat(ZooKeeper zooKeeper, String path, boolean watch) {
		return getStat(zooKeeper,path,watch,
			NoAuthStrategy.Default, AuthFailedStrategy.Default, SessionExpiredStrategy.Default, 
			ConnectionLossStrategy.Default,InterruptedStrategy.Default
		);
	}
	
	
	public static Stat getStat(ZooKeeper zooKeeper, String path, Watcher watcher) {
		return getStat(zooKeeper,path,watcher,
			NoAuthStrategy.Default, AuthFailedStrategy.Default, SessionExpiredStrategy.Default, 
			ConnectionLossStrategy.Default,InterruptedStrategy.Default
		);
	}
	
	public static Stat getStat(ZooKeeper zooKeeper, String path, boolean watch, 
			NoAuthStrategy noAuthStrategy, AuthFailedStrategy authFailedStrategy, SessionExpiredStrategy sessionExpiredStrategy, 
			ConnectionLossStrategy connectionLossStrategy, InterruptedStrategy interruptedStrategy) {
		
		try {
			return zooKeeper.exists(path, watch);
		} catch (InterruptedException e) {
			
			switch(interruptedStrategy){
			case Ignore:
				break;
			case RetryAlways:
				for(;;){
					try {
						return getStat(zooKeeper,path,watch,
							noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
							connectionLossStrategy, InterruptedStrategy.Default
							);
					} catch (InterruptedRuntimeException e1) {
						// retry again
					}
				}
			case RetryOne:
				return getStat(zooKeeper,path,watch,
						noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
						connectionLossStrategy, InterruptedStrategy.Default
						);
			case Default:
			default:
				throw new InterruptedRuntimeException(e);
			}
			
		} catch (KeeperException e) {

			switch (e.code()) {
			case NONODE:
				break;
			case AUTHFAILED:
				switch(authFailedStrategy){
				case Ignore:
					break;
				case Default:
				default:
					throw new KeeperRuntimeException(e);
				}
				break;
			case SESSIONEXPIRED:
				switch(sessionExpiredStrategy){
				case Ignore:
					break;
				case Default:
				default:
					throw new KeeperRuntimeException(e);
				}
				break;
			case CONNECTIONLOSS:
				// 无限次重试
				switch(connectionLossStrategy){
				case Ignore:
					break;
				case RetryAlways:
					for(;;){
						try {
							return getStat(zooKeeper,path,watch,
									noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
									ConnectionLossStrategy.Default, interruptedStrategy
									);
						} catch (KeeperRuntimeException e1) {
							if(e1.getCause().code() == KeeperException.Code.CONNECTIONLOSS){
								// retry again								
							}else{
								throw e1;								
							}
						}
					}
				case RetryOne:
					return getStat(zooKeeper,path,watch,
							noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
							ConnectionLossStrategy.Default, interruptedStrategy
							);
				case Default:
				default:
					throw new KeeperRuntimeException(e);
				
				}
				break;
			case NOAUTH:
				switch(noAuthStrategy){
				case Ignore:
					break;
				case Default:
				default:
					throw new KeeperRuntimeException(e);
				}
				break;
			default:
				throw new KeeperRuntimeException(e);
				
			}
		}
		return null;
	}
	public static Stat getStat(ZooKeeper zooKeeper, String path, Watcher watcher, 
			NoAuthStrategy noAuthStrategy, AuthFailedStrategy authFailedStrategy, SessionExpiredStrategy sessionExpiredStrategy, 
			ConnectionLossStrategy connectionLossStrategy, InterruptedStrategy interruptedStrategy) {
		
		try {
			return zooKeeper.exists(path, watcher);
		} catch (InterruptedException e) {
			
			switch(interruptedStrategy){
			case Ignore:
				break;
			case RetryAlways:
				for(;;){
					try {
						return getStat(zooKeeper,path,watcher,
							noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
							connectionLossStrategy, InterruptedStrategy.Default
							);
					} catch (InterruptedRuntimeException e1) {
						// retry again
					}
				}
			case RetryOne:
				return getStat(zooKeeper,path,watcher,
						noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
						connectionLossStrategy, InterruptedStrategy.Default
						);
			case Default:
			default:
				throw new InterruptedRuntimeException(e);
			}
			
		} catch (KeeperException e) {

			switch (e.code()) {
			case NONODE:
				break;
			case AUTHFAILED:
				switch(authFailedStrategy){
				case Ignore:
					break;
				case Default:
				default:
					throw new KeeperRuntimeException(e);
				}
				break;
			case SESSIONEXPIRED:
				switch(sessionExpiredStrategy){
				case Ignore:
					break;
				case Default:
				default:
					throw new KeeperRuntimeException(e);
				}
				break;
			case CONNECTIONLOSS:
				// 无限次重试
				switch(connectionLossStrategy){
				case Ignore:
					break;
				case RetryAlways:
					for(;;){
						try {
							return getStat(zooKeeper,path,watcher,
									noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
									ConnectionLossStrategy.Default, interruptedStrategy
									);
						} catch (KeeperRuntimeException e1) {
							if(e1.getCause().code() == KeeperException.Code.CONNECTIONLOSS){
								// retry again								
							}else{
								throw e1;								
							}
						}
					}
				case RetryOne:
					return getStat(zooKeeper,path,watcher,
							noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
							ConnectionLossStrategy.Default, interruptedStrategy
							);
				case Default:
				default:
					throw new KeeperRuntimeException(e);
				
				}
				break;
			case NOAUTH:
				switch(noAuthStrategy){
				case Ignore:
					break;
				case Default:
				default:
					throw new KeeperRuntimeException(e);
				}
				break;
			default:
				throw new KeeperRuntimeException(e);
				
			}
		}
		return null;
	}
	
///////////////////////////////////////////////////////////////////////////
// getData
///////////////////////////////////////////////////////////////////////////
//ZooKeeper.getData
//
//– getData(String path, boolean watch, Stat stat)
//
//NONODE     NoNodeException     - 节点不存在
//
	public static byte[] getData(ZooKeeper zooKeeper, String path) 
	{
		return getData(zooKeeper,path,false,null,
				NoAuthStrategy.Default, AuthFailedStrategy.Default, SessionExpiredStrategy.Default, 
				ConnectionLossStrategy.RetryAlways,InterruptedStrategy.RetryAlways, 
				GetDataStrategy.ReturnEmptyArray);
	}
	
	public static byte[] getData(ZooKeeper zooKeeper, String path, Stat stat) 
	{
		return getData(zooKeeper,path,false,stat,
				NoAuthStrategy.Default, AuthFailedStrategy.Default, SessionExpiredStrategy.Default, 
				ConnectionLossStrategy.Default,InterruptedStrategy.Default, 
				GetDataStrategy.ReturnEmptyArray);
	}
	
	public static byte[] getData(ZooKeeper zooKeeper, String path, boolean watch, Stat stat,
			GetDataStrategy getDataStrategy) 
	{
		return getData(zooKeeper,path,watch,stat,
				NoAuthStrategy.Default, AuthFailedStrategy.Default, SessionExpiredStrategy.Default, 
				ConnectionLossStrategy.Default,InterruptedStrategy.Default, 
				getDataStrategy);
	}
	
	public static byte[] getData(ZooKeeper zooKeeper, String path, boolean watch, Stat stat,
			NoAuthStrategy noAuthStrategy, AuthFailedStrategy authFailedStrategy, SessionExpiredStrategy sessionExpiredStrategy, 
			ConnectionLossStrategy connectionLossStrategy, InterruptedStrategy interruptedStrategy, 
			GetDataStrategy getDataStrategy) 
	{
		try {
			return zooKeeper.getData(path, watch, stat);
		} catch (InterruptedException e) {
			
			switch(interruptedStrategy){
			case Ignore:
				break;
			case RetryAlways:
				for(;;){
					try {
						return getData(zooKeeper,path,watch,stat,
							noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
							connectionLossStrategy, InterruptedStrategy.Default, 
							getDataStrategy);
					} catch (InterruptedRuntimeException e1) {
						// retry again
					}
				}
			case RetryOne:
				return getData(zooKeeper,path,watch,stat,
						noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
						connectionLossStrategy, InterruptedStrategy.Default, 
						getDataStrategy);
			case Default:
			default:
				throw new InterruptedRuntimeException(e);
			}
			
		} catch (KeeperException e) {

			switch (e.code()) {
			case NONODE:
				break;
			case AUTHFAILED:
				switch(authFailedStrategy){
				case Ignore:
					break;
				case Default:
				default:
					throw new KeeperRuntimeException(e);
				}
				break;
			case SESSIONEXPIRED:
				switch(sessionExpiredStrategy){
				case Ignore:
					break;
				case Default:
				default:
					throw new KeeperRuntimeException(e);
				}
				break;
			case CONNECTIONLOSS:
				// 无限次重试
				switch(connectionLossStrategy){
				case Ignore:
					break;
				case RetryAlways:
					for(;;){
						try {
							return getData(zooKeeper,path,watch,stat,
									noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
									ConnectionLossStrategy.Default, interruptedStrategy, 
									getDataStrategy);
						} catch (KeeperRuntimeException e1) {
							if(e1.getCause().code() == KeeperException.Code.CONNECTIONLOSS){
								// retry again								
							}else{
								throw e1;								
							}
						}
					}
				case RetryOne:
					return getData(zooKeeper,path,watch,stat,
							noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
							ConnectionLossStrategy.Default, interruptedStrategy, 
							getDataStrategy);
				case Default:
				default:
					throw new KeeperRuntimeException(e);
				
				}
				break;
			case NOAUTH:
				switch(noAuthStrategy){
				case Ignore:
					break;
				case Default:
				default:
					throw new KeeperRuntimeException(e);
				}
				break;
			default:
				throw new KeeperRuntimeException(e);
				
			}
		}
		
		switch(getDataStrategy){
		case ReturnNull: return null;
		case Default:
		case ReturnEmptyArray: 
		default:
			return EMPTY_BYTES;
		}
	}

	public static byte[] getData(ZooKeeper zooKeeper, String path, Watcher watcher, Stat stat,
			NoAuthStrategy noAuthStrategy, AuthFailedStrategy authFailedStrategy, SessionExpiredStrategy sessionExpiredStrategy, 
			ConnectionLossStrategy connectionLossStrategy, InterruptedStrategy interruptedStrategy, 
			GetDataStrategy getDataStrategy) 
	{
		try {
			return zooKeeper.getData(path, watcher, stat);
		} catch (InterruptedException e) {
			
			switch(interruptedStrategy){
			case Ignore:
				break;
			case RetryAlways:
				for(;;){
					try {
						return getData(zooKeeper,path,watcher,stat,
							noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
							connectionLossStrategy, InterruptedStrategy.Default, 
							getDataStrategy);
					} catch (InterruptedRuntimeException e1) {
						// retry again
					}
				}
			case RetryOne:
				return getData(zooKeeper,path,watcher,stat,
						noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
						connectionLossStrategy, InterruptedStrategy.Default, 
						getDataStrategy);
			case Default:
			default:
				throw new InterruptedRuntimeException(e);
			}
			
		} catch (KeeperException e) {

			switch (e.code()) {
			case NONODE:
				break;
			case AUTHFAILED:
				switch(authFailedStrategy){
				case Ignore:
					break;
				case Default:
				default:
					throw new KeeperRuntimeException(e);
				}
				break;
			case SESSIONEXPIRED:
				switch(sessionExpiredStrategy){
				case Ignore:
					break;
				case Default:
				default:
					throw new KeeperRuntimeException(e);
				}
				break;
			case CONNECTIONLOSS:
				// 无限次重试
				switch(connectionLossStrategy){
				case Ignore:
					break;
				case RetryAlways:
					for(;;){
						try {
							return getData(zooKeeper,path,watcher,stat,
									noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
									ConnectionLossStrategy.Default, interruptedStrategy, 
									getDataStrategy);
						} catch (KeeperRuntimeException e1) {
							if(e1.getCause().code() == KeeperException.Code.CONNECTIONLOSS){
								// retry again								
							}else{
								throw e1;								
							}
						}
					}
				case RetryOne:
					return getData(zooKeeper,path,watcher,stat,
							noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
							ConnectionLossStrategy.Default, interruptedStrategy, 
							getDataStrategy);
				case Default:
				default:
					throw new KeeperRuntimeException(e);
				
				}
				break;
			case NOAUTH:
				switch(noAuthStrategy){
				case Ignore:
					break;
				case Default:
				default:
					throw new KeeperRuntimeException(e);
				}
				break;
			default:
				throw new KeeperRuntimeException(e);
				
			}
		}
		
		switch(getDataStrategy){
		case ReturnNull: return null;
		case Default:
		case ReturnEmptyArray: 
		default:
			return EMPTY_BYTES;
		}
	}
	
	public static <T> T readObject(ZooKeeper zooKeeper, String path) {
		return readObject(zooKeeper,path,null);
	}
	
	@SuppressWarnings("unchecked")
	public static <T> T readObject(ZooKeeper zooKeeper, String path, T def) {
		byte[] data = getData(zooKeeper, path);
		if(data.length==0) {
			return def;
		}
		try(ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(data))){
        	return (T)ois.readObject();
        }catch(Exception e){
        	e.printStackTrace();
        	// TODO 写日志
        	return def;
        }
	}

	public static <T> T readObject(ZooKeeper zooKeeper, String path, Serializer serializer) {
		return readObject(zooKeeper,path,serializer,null);
	}
	
	@SuppressWarnings("unchecked")
	public static <T> T readObject(ZooKeeper zooKeeper, String path, Serializer serializer, T def) {
		byte[] data = getData(zooKeeper, path);
		if(data.length==0) {
			return def;
		}
		try{
        	return (T)serializer.deserialize(data);
        }catch(Exception e){
        	e.printStackTrace();
        	// TODO 写日志
        	return def;
        }
	}
	
	public static String readString(ZooKeeper zooKeeper, String path, String def) {
		byte[] data = getData(zooKeeper, path);
		if(data.length==0) {
			return def;
		}else{
			return new String(data);
		}
	}
	
	public static String readString(ZooKeeper zooKeeper, String path, Charset charset, String def) {
		byte[] data = getData(zooKeeper, path);
		if(data.length==0) {
			return def;
		}else{
			return new String(data, charset);
		}
	}
	
///////////////////////////////////////////////////////////////////////////
// setData
///////////////////////////////////////////////////////////////////////////
	
//ZooKeeper.setData
//
//NONODE     NoNodeException     - 节点不存在
//BADVERSION BadVersionException - 版本号不一致

	public static Stat setData(ZooKeeper zooKeeper, String path, byte[] data, SetDataStrategy... setDataStrategies) 
		throws InterruptedRuntimeException, KeeperRuntimeException 
	{
		return setData(zooKeeper,path,data,-1,
				NoAuthStrategy.Default, AuthFailedStrategy.Default, SessionExpiredStrategy.Default, 
				ConnectionLossStrategy.RetryAlways,InterruptedStrategy.RetryAlways, 
				setDataStrategies);
	}
	
	public static Stat setData(ZooKeeper zooKeeper, String path, byte[] data, int version, SetDataStrategy... setDataStrategies) 
		throws InterruptedRuntimeException, KeeperRuntimeException 
	{
		return setData(zooKeeper,path,data,version,
				NoAuthStrategy.Default, AuthFailedStrategy.Default, SessionExpiredStrategy.Default, 
				ConnectionLossStrategy.RetryAlways,InterruptedStrategy.RetryAlways, 
				setDataStrategies);
	}
	
	public static Stat setData(ZooKeeper zooKeeper, String path, byte[] data, int version,  
		NoAuthStrategy noAuthStrategy, AuthFailedStrategy authFailedStrategy, SessionExpiredStrategy sessionExpiredStrategy, 
		ConnectionLossStrategy connectionLossStrategy, InterruptedStrategy interruptedStrategy,
		SetDataStrategy... setDataStrategies) 
		throws InterruptedRuntimeException, KeeperRuntimeException 
	{
		try {
			return zooKeeper.setData(path, data, version);
		} catch (InterruptedException e) {
			
			switch(interruptedStrategy){
			case Ignore:
				break;
			case RetryAlways:
				for(;;){
					try {
						return setData(zooKeeper,path,data, version,
							noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
							connectionLossStrategy, InterruptedStrategy.Default,
							setDataStrategies);
					} catch (InterruptedRuntimeException e1) {
						// retry again
					}
				}
			case RetryOne:
				return setData(zooKeeper,path,data,version,
						noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
						connectionLossStrategy, InterruptedStrategy.Default,
						setDataStrategies);
			case Default:
			default:
				throw new InterruptedRuntimeException(e);
			}
		} catch (KeeperException e) {
			
			List<SetDataStrategy> strategies = Arrays.asList(setDataStrategies);
			
			switch (e.code()) {
			case NONODE:
				
				if(strategies.contains(SetDataStrategy.CreateRecursively)){
					if(create(zooKeeper, path, data, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT,
							noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
							connectionLossStrategy, interruptedStrategy, CreateStrategy.CreateRecursively)){
						return getStat(zooKeeper, path,false,
								noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
								connectionLossStrategy, interruptedStrategy);						
					}else{
						return null;
					}
				}else if(strategies.contains(SetDataStrategy.CreateIfNotExists)){
					if(create(zooKeeper, path, data,Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT,
							noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
							connectionLossStrategy, interruptedStrategy)){
						return getStat(zooKeeper, path,false,
								noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
								connectionLossStrategy, interruptedStrategy);
					}else{
						return null;
					}
				}else if(strategies.contains(SetDataStrategy.Ignore)){
					return null;
				}else if(strategies.contains(SetDataStrategy.Default)){
					throw new KeeperRuntimeException(e);
				}else{
					throw new KeeperRuntimeException(e);
				}
				
			case BADVERSION:

				if(strategies.contains(SetDataStrategy.UpdateAnyway)){

					if(version<0) {
						throw new KeeperRuntimeException(e);
					}
					
					return setData(zooKeeper,path,data,-1,
							noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
							connectionLossStrategy, interruptedStrategy,
							setDataStrategies);
				}else if(strategies.contains(SetDataStrategy.Ignore)){
					return null;
				}else if(strategies.contains(SetDataStrategy.Default)){
					throw new KeeperRuntimeException(e);
				}else{
					throw new KeeperRuntimeException(e);
				}
			case AUTHFAILED:
				switch(authFailedStrategy){
				case Ignore:
					break;
				case Default:
				default:
					throw new KeeperRuntimeException(e);
				}
				break;
			case SESSIONEXPIRED:
				switch(sessionExpiredStrategy){
				case Ignore:
					break;
				case Default:
				default:
					throw new KeeperRuntimeException(e);
				}
				break;
			case CONNECTIONLOSS:
				// 无限次重试
				switch(connectionLossStrategy){
				case Ignore:
					break;
				case RetryAlways:
					for(;;){
						try {
							return setData(zooKeeper,path,data,version,
									noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
									ConnectionLossStrategy.Default, interruptedStrategy,
									setDataStrategies);
						} catch (KeeperRuntimeException e1) {
							if(e1.getCause().code() == KeeperException.Code.CONNECTIONLOSS){
								// retry again								
							}else{
								throw e1;								
							}
						}
					}
				case RetryOne:
					return setData(zooKeeper,path,data,version,
							noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
							ConnectionLossStrategy.Default, interruptedStrategy,
							setDataStrategies);
				case Default:
				default:
					throw new KeeperRuntimeException(e);
				
				}
				break;
			case NOAUTH:
				switch(noAuthStrategy){
				case Ignore:
					break;
				case Default:
				default:
					throw new KeeperRuntimeException(e);
				}
				break;
			default:
				throw new KeeperRuntimeException(e);
				
			}
		}

		return null;
	}

	public static Stat writeObject(ZooKeeper zooKeeper, String path, Object obj, SetDataStrategy... setDataStrategies) 
		throws InterruptedRuntimeException, KeeperRuntimeException 
	{
		return writeObject(zooKeeper, path, obj, -1, setDataStrategies);
	}

	public static Stat writeObject(ZooKeeper zooKeeper, String path, Object obj, int version, SetDataStrategy... setDataStrategies) 
		throws InterruptedRuntimeException, KeeperRuntimeException 
	{
		
		ByteArrayOutputStream os = new ByteArrayOutputStream();
	   	try(ObjectOutputStream oos = new ObjectOutputStream(os)){
    		oos.writeObject(obj);
        } catch (IOException e) {
			e.printStackTrace();
			return null;
		}
	   	
		return setData(zooKeeper,path,os.toByteArray(),version,
			NoAuthStrategy.Default, AuthFailedStrategy.Default, SessionExpiredStrategy.Default, 
			ConnectionLossStrategy.RetryAlways,InterruptedStrategy.RetryAlways, 
			setDataStrategies);
	}

	public static Stat writeObject(ZooKeeper zooKeeper, String path, Object obj, Serializer serializer, SetDataStrategy... setDataStrategies) 
		throws InterruptedRuntimeException, KeeperRuntimeException 
	{
		return writeObject(zooKeeper, path, obj, -1, serializer, setDataStrategies);
	}

	public static Stat writeObject(ZooKeeper zooKeeper, String path, Object obj, int version, Serializer serializer, SetDataStrategy... setDataStrategies) 
		throws InterruptedRuntimeException, KeeperRuntimeException 
	{
		try{
			return setData(zooKeeper,path,serializer.serialize(obj),version,
				NoAuthStrategy.Default, AuthFailedStrategy.Default, SessionExpiredStrategy.Default, 
				ConnectionLossStrategy.RetryAlways,InterruptedStrategy.RetryAlways, 
				setDataStrategies);
        } catch (SerializeException e) {
			e.printStackTrace();
			return null;
		}
	}
		
	///////////////////////////////////////////////////////////////////////////
	// getChildren
	///////////////////////////////////////////////////////////////////////////
//	NONODE NoNodeException - 节点不存在
	
	public static List<String> getChildren(ZooKeeper zooKeeper, String path) {
		return getChildren(zooKeeper,path,false,null,
				NoAuthStrategy.Default, AuthFailedStrategy.Default, SessionExpiredStrategy.Default, 
				ConnectionLossStrategy.RetryAlways,InterruptedStrategy.RetryAlways, 
				GetChildrenStrategy.ReturnEmptyList);
	}
	
	public static List<String> getChildren(ZooKeeper zooKeeper, String path, boolean watch, Stat stat) {
		return getChildren(zooKeeper,path,watch,stat,
				NoAuthStrategy.Default, AuthFailedStrategy.Default, SessionExpiredStrategy.Default, 
				ConnectionLossStrategy.Default,InterruptedStrategy.Default, 
				GetChildrenStrategy.ReturnEmptyList);
	}

	public static List<String> getChildren(ZooKeeper zooKeeper, String path, 
			NoAuthStrategy noAuthStrategy, AuthFailedStrategy authFailedStrategy, SessionExpiredStrategy sessionExpiredStrategy, 
			ConnectionLossStrategy connectionLossStrategy, InterruptedStrategy interruptedStrategy, 
			GetChildrenStrategy getChildrenStrategy) {
		return getChildren(zooKeeper,path,false,null,
				noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
				connectionLossStrategy, InterruptedStrategy.Default, 
				getChildrenStrategy);
	}
	
	public static List<String> getChildren(ZooKeeper zooKeeper, String path, boolean watch, Stat stat,
			NoAuthStrategy noAuthStrategy, AuthFailedStrategy authFailedStrategy, SessionExpiredStrategy sessionExpiredStrategy, 
			ConnectionLossStrategy connectionLossStrategy, InterruptedStrategy interruptedStrategy, 
			GetChildrenStrategy getChildrenStrategy) {
		
		try {
			return zooKeeper.getChildren(path, watch, stat);
		} catch (InterruptedException e) {
			
			switch(interruptedStrategy){
			case Ignore:
				break;
			case RetryAlways:
				for(;;){
					try {
						return getChildren(zooKeeper,path,watch,stat,
							noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
							connectionLossStrategy, InterruptedStrategy.Default, 
							getChildrenStrategy);
					} catch (InterruptedRuntimeException e1) {
						// retry again
					}
				}
			case RetryOne:
				return getChildren(zooKeeper,path,watch,stat,
						noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
						connectionLossStrategy, InterruptedStrategy.Default, 
						getChildrenStrategy);
			case Default:
			default:
				throw new InterruptedRuntimeException(e);
			}
			
		} catch (KeeperException e) {

			switch (e.code()) {
			case NONODE:
				break;
			case AUTHFAILED:
				switch(authFailedStrategy){
				case Ignore:
					break;
				case Default:
				default:
					throw new KeeperRuntimeException(e);
				}
				break;
			case SESSIONEXPIRED:
				switch(sessionExpiredStrategy){
				case Ignore:
					break;
				case Default:
				default:
					throw new KeeperRuntimeException(e);
				}
				break;
			case CONNECTIONLOSS:
				// 无限次重试
				switch(connectionLossStrategy){
				case Ignore:
					break;
				case RetryAlways:
					for(;;){
						try {
							return getChildren(zooKeeper,path,watch,stat,
									noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
									ConnectionLossStrategy.Default, interruptedStrategy, 
									getChildrenStrategy);
						} catch (KeeperRuntimeException e1) {
							if(e1.getCause().code() == KeeperException.Code.CONNECTIONLOSS){
								// retry again								
							}else{
								throw e1;								
							}
						}
					}
				case RetryOne:
					return getChildren(zooKeeper,path,watch,stat,
							noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
							ConnectionLossStrategy.Default, interruptedStrategy, 
							getChildrenStrategy);
				case Default:
				default:
					throw new KeeperRuntimeException(e);
				
				}
				break;
			case NOAUTH:
				switch(noAuthStrategy){
				case Ignore:
					break;
				case Default:
				default:
					throw new KeeperRuntimeException(e);
				}
				break;
			default:
				throw new KeeperRuntimeException(e);
				
			}
		}
		
		switch(getChildrenStrategy){
		case ReturnNull: return null;
		case Default:
		case ReturnEmptyList: 
		default:
			return Collections.emptyList();
		}
	}

	
	public static List<String> getChildren(ZooKeeper zooKeeper, String path, Watcher watcher) {
		return getChildren(zooKeeper,path,watcher,null,
				NoAuthStrategy.Default, AuthFailedStrategy.Default, SessionExpiredStrategy.Default, 
				ConnectionLossStrategy.Default,InterruptedStrategy.Default, 
				GetChildrenStrategy.ReturnEmptyList);
	}
	
	public static List<String> getChildren(ZooKeeper zooKeeper, String path, Watcher watcher, Stat stat) {
		return getChildren(zooKeeper,path,watcher,stat,
				NoAuthStrategy.Default, AuthFailedStrategy.Default, SessionExpiredStrategy.Default, 
				ConnectionLossStrategy.Default,InterruptedStrategy.Default, 
				GetChildrenStrategy.ReturnEmptyList);
	}
	
	public static List<String> getChildren(ZooKeeper zooKeeper, String path, Watcher watcher, Stat stat,
			NoAuthStrategy noAuthStrategy, AuthFailedStrategy authFailedStrategy, SessionExpiredStrategy sessionExpiredStrategy, 
			ConnectionLossStrategy connectionLossStrategy, InterruptedStrategy interruptedStrategy, 
			GetChildrenStrategy getChildrenStrategy) {
		
		try {
			return zooKeeper.getChildren(path, watcher, stat);
		} catch (InterruptedException e) {
			
			switch(interruptedStrategy){
			case Ignore:
				break;
			case RetryAlways:
				for(;;){
					try {
						return getChildren(zooKeeper,path,watcher,stat,
							noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
							connectionLossStrategy, InterruptedStrategy.Default, 
							getChildrenStrategy);
					} catch (InterruptedRuntimeException e1) {
						// retry again
					}
				}
			case RetryOne:
				return getChildren(zooKeeper,path,watcher,stat,
						noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
						connectionLossStrategy, InterruptedStrategy.Default, 
						getChildrenStrategy);
			case Default:
			default:
				throw new InterruptedRuntimeException(e);
			}
			
		} catch (KeeperException e) {

			switch (e.code()) {
			case NONODE:
				break;
			case AUTHFAILED:
				switch(authFailedStrategy){
				case Ignore:
					break;
				case Default:
				default:
					throw new KeeperRuntimeException(e);
				}
				break;
			case SESSIONEXPIRED:
				switch(sessionExpiredStrategy){
				case Ignore:
					break;
				case Default:
				default:
					throw new KeeperRuntimeException(e);
				}
				break;
			case CONNECTIONLOSS:
				// 无限次重试
				switch(connectionLossStrategy){
				case Ignore:
					break;
				case RetryAlways:
					for(;;){
						try {
							return getChildren(zooKeeper,path,watcher,stat,
									noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
									ConnectionLossStrategy.Default, interruptedStrategy, 
									getChildrenStrategy);
						} catch (KeeperRuntimeException e1) {
							if(e1.getCause().code() == KeeperException.Code.CONNECTIONLOSS){
								// retry again								
							}else{
								throw e1;								
							}
						}
					}
				case RetryOne:
					return getChildren(zooKeeper,path,watcher,stat,
							noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
							ConnectionLossStrategy.Default, interruptedStrategy, 
							getChildrenStrategy);
				case Default:
				default:
					throw new KeeperRuntimeException(e);
				
				}
				break;
			case NOAUTH:
				switch(noAuthStrategy){
				case Ignore:
					break;
				case Default:
				default:
					throw new KeeperRuntimeException(e);
				}
				break;
			default:
				throw new KeeperRuntimeException(e);
				
			}
		}
		
		switch(getChildrenStrategy){
		case ReturnNull: return null;
		case Default:
		case ReturnEmptyList: 
		default:
			return Collections.emptyList();
		}
	}
	
	///////////////////////////////////////////////////////////////////////////
	// delete
	///////////////////////////////////////////////////////////////////////////
//	NONODE     NoNodeException     - 节点不存在
	// 对应策略 1. 向上抛异常 2. 忽略
//	BADVERSION BadVersionException - 版本号不一致 
	// 对应策略 1. 向上抛异常 2. 忽略 3. 强制删除
//	NOTEMPTY   NotEmptyException   - 节点有子节点, 不允许删除
	// 对应策略 1. 向上抛异常 2. 忽略 3. 递归删除
	
	public static boolean deleteRecursively(ZooKeeper zooKeeper, String path) 
			throws InterruptedRuntimeException, KeeperRuntimeException 
	{
		return delete(zooKeeper,path,-1,
				NoAuthStrategy.Default, AuthFailedStrategy.Default, SessionExpiredStrategy.Default, 
				ConnectionLossStrategy.Default,InterruptedStrategy.Default,
				DeleteStrategy.DeleteRecursively);
	}
	
	public static boolean delete(ZooKeeper zooKeeper, String path, int version, DeleteStrategy... deleteStrategies ) 
		throws InterruptedRuntimeException, KeeperRuntimeException 
	{
		return delete(zooKeeper,path,version,
				NoAuthStrategy.Default, AuthFailedStrategy.Default, SessionExpiredStrategy.Default, 
				ConnectionLossStrategy.Default,InterruptedStrategy.Default,
				deleteStrategies);
	}
	
	
	public static boolean delete(ZooKeeper zooKeeper, String path, int version,  
		NoAuthStrategy noAuthStrategy, AuthFailedStrategy authFailedStrategy, SessionExpiredStrategy sessionExpiredStrategy, 
		ConnectionLossStrategy connectionLossStrategy, InterruptedStrategy interruptedStrategy,
		DeleteStrategy... deleteStrategies ) 
		throws InterruptedRuntimeException, KeeperRuntimeException 
	{
		try {
			zooKeeper.delete(path, version);
			return true;
		} catch (InterruptedException e) {
			
			switch(interruptedStrategy){
			case Ignore:
				break;
			case RetryAlways:
				for(;;){
					try {
						return delete(zooKeeper,path,version,
							noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
							connectionLossStrategy, InterruptedStrategy.Default,
							deleteStrategies);
					} catch (InterruptedRuntimeException e1) {
						// retry again
					}
				}
			case RetryOne:
				return delete(zooKeeper,path,version,
						noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
						connectionLossStrategy, InterruptedStrategy.Default,
						deleteStrategies);
			case Default:
			default:
				throw new InterruptedRuntimeException(e);
			}
		} catch (KeeperException e) {

			if(deleteStrategies.length==0) {
				throw new KeeperRuntimeException(e);
			}
			
			List<DeleteStrategy> strategies = Arrays.asList(deleteStrategies);
			
			switch (e.code()) {
			case NONODE:
				return true;
			case BADVERSION:
				if(strategies.contains(DeleteStrategy.DeleteAnyway)){
					
					if(version<0) {
						throw new KeeperRuntimeException(e);
					}
					
					return delete(zooKeeper,path,-1,
							noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
							connectionLossStrategy, interruptedStrategy,
							deleteStrategies);			
				}
				if(strategies.contains(CreateStrategy.Ignore)){ return false; }
				throw new KeeperRuntimeException(e);
			case NOTEMPTY:
				if(strategies.contains(DeleteStrategy.DeleteRecursively)){
					Stat stat = new Stat();
					List<String> children = getChildren(zooKeeper, path, false,stat,
							noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
							connectionLossStrategy, interruptedStrategy,
							GetChildrenStrategy.ReturnEmptyList);
					for (String child : children) {
						boolean success = delete(zooKeeper,path+"/"+child,-1,
								noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
								connectionLossStrategy, interruptedStrategy, 
								deleteStrategies);
						if(!success){
							return false;
						}
					}
					
					return delete(zooKeeper,path,version,
							noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
							connectionLossStrategy, interruptedStrategy,
							deleteStrategies);			
				}
				
				if(strategies.contains(CreateStrategy.Ignore)){ return false; }
				throw new KeeperRuntimeException(e);
			case AUTHFAILED:
				switch(authFailedStrategy){
				case Ignore:
					break;
				case Default:
				default:
					throw new KeeperRuntimeException(e);
				}
				break;
			case SESSIONEXPIRED:
				switch(sessionExpiredStrategy){
				case Ignore:
					break;
				case Default:
				default:
					throw new KeeperRuntimeException(e);
				}
				break;
			case CONNECTIONLOSS:
				// 无限次重试
				switch(connectionLossStrategy){
				case Ignore:
					break;
				case RetryAlways:
					for(;;){
						try {
							return delete(zooKeeper,path,version,
									noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
									ConnectionLossStrategy.Default, interruptedStrategy,
									deleteStrategies);
						} catch (KeeperRuntimeException e1) {
							if(e1.getCause().code() == KeeperException.Code.CONNECTIONLOSS){
								// retry again								
							}else{
								throw e1;								
							}
						}
					}
				case RetryOne:
					return delete(zooKeeper,path,version,
							noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
							ConnectionLossStrategy.Default, interruptedStrategy,
							deleteStrategies);
				case Default:
				default:
					throw new KeeperRuntimeException(e);
				
				}
				break;
			case NOAUTH:
				switch(noAuthStrategy){
				case Ignore:
					break;
				case Default:
				default:
					throw new KeeperRuntimeException(e);
				}
				break;
			default:
				throw new KeeperRuntimeException(e);
				
			}
		}

		return false;
	}

	///////////////////////////////////////////////////////////////////////////
	// create
	///////////////////////////////////////////////////////////////////////////
//	NODEEXISTS              NodeExistsException - 节点已存在
	// 对应策略 1. 向上抛异常 2. 忽略 3. 删除重建
//	NONODE                  NoNodeException - 祖先节点不存在
	// 对应策略 1. 向上抛异常 2. 自动创建祖先节点
//	NOCHILDRENFOREPHEMERALS NoChildrenForEphemeralsException - 父亲节点是临时节点
	// 对应策略 1. 向上抛异常
//	INVALIDACL              InvalidACLException - 访问控制列表不正确
	// 对应策略 1. 向上抛异常
//	NOAUTH                  NoAuthException - 父亲节点没有CREATE权限
	// 对应策略 1. 向上抛异常
//	AUTHFAILED     AuthFailedException - ???
	// 对应策略 1. 向上抛异常
//	SESSIONEXPIRED SessionExpiredException - 没得救了, 重新建立连接, 重新建立会话吧
	// 对应策略 1. 向上抛异常
//	CONNECTIONLOSS ConnectionLossException - 等ZooKeeper重新连接再重试
	// 对应策略 1. 向上抛异常 无限次重试
	
	public static boolean create(ZooKeeper zooKeeper, String path, CreateStrategy... createStrategies) throws InterruptedRuntimeException, KeeperRuntimeException 
	{
		return create(zooKeeper,path,EMPTY_BYTES,Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT,
				NoAuthStrategy.Default, AuthFailedStrategy.Default, SessionExpiredStrategy.Default, 
				ConnectionLossStrategy.RetryAlways,InterruptedStrategy.RetryAlways,
				createStrategies);
	}	
	
	public static boolean create(ZooKeeper zooKeeper, String path, byte[] data, CreateStrategy... createStrategies) throws InterruptedRuntimeException, KeeperRuntimeException
	{
		return create(zooKeeper,path,data,Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT,
				NoAuthStrategy.Default, AuthFailedStrategy.Default, SessionExpiredStrategy.Default, 
				ConnectionLossStrategy.RetryAlways,InterruptedStrategy.RetryAlways,
				createStrategies);
	}
	public static boolean create(ZooKeeper zooKeeper, String path, byte[] data, CreateMode createMode, CreateStrategy... createStrategies)
		throws InterruptedRuntimeException, KeeperRuntimeException
	{
		return create(zooKeeper,path,data,Ids.OPEN_ACL_UNSAFE,createMode,
				NoAuthStrategy.Default, AuthFailedStrategy.Default, SessionExpiredStrategy.Default, 
				ConnectionLossStrategy.RetryAlways,InterruptedStrategy.RetryAlways,
				createStrategies);
	}
	public static boolean create(ZooKeeper zooKeeper, String path, byte[] data, List<ACL> acl, CreateMode createMode, CreateStrategy... createStrategies)
		throws InterruptedRuntimeException, KeeperRuntimeException
	{
		return create(zooKeeper,path,data,acl,createMode,
				NoAuthStrategy.Default, AuthFailedStrategy.Default, SessionExpiredStrategy.Default, 
				ConnectionLossStrategy.RetryAlways,InterruptedStrategy.RetryAlways,
				createStrategies);
	}
	public static boolean create(ZooKeeper zooKeeper, String path, byte[] data, InterruptedStrategy interruptedStrategy, CreateStrategy... createStrategies) 
		throws InterruptedRuntimeException, KeeperRuntimeException
	{
		return create(zooKeeper,path,data,Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT,
				NoAuthStrategy.Default, AuthFailedStrategy.Default, SessionExpiredStrategy.Default, 
				ConnectionLossStrategy.RetryAlways,interruptedStrategy, 
				createStrategies);
	}
	public static boolean create(ZooKeeper zooKeeper, String path, byte[] data, CreateMode createMode, 
		InterruptedStrategy interruptedStrategy, CreateStrategy... createStrategies) 
		throws InterruptedRuntimeException, KeeperRuntimeException
	{
		return create(zooKeeper,path,data,Ids.OPEN_ACL_UNSAFE,createMode,
				NoAuthStrategy.Default, AuthFailedStrategy.Default, SessionExpiredStrategy.Default, 
				ConnectionLossStrategy.RetryAlways,interruptedStrategy, 
				createStrategies);
	}
	
	public static boolean createEphemeralRecursively(ZooKeeper zooKeeper, String path) 
		throws InterruptedRuntimeException, KeeperRuntimeException
	{
		return createEphemeralRecursively(zooKeeper,path,EMPTY_BYTES);
	}

	/** 
	 * 创建临时节点, 
	 * 如果路径不存在,则递归创建, 
	 * 遇到状态异常返回false, 
	 * 遇到可恢复异常无限重试, 
	 * 遇到不可恢复异常重新抛出
	 * 
	 * @return true: 创建成功, false: 创建失败
	 * */
	public static boolean createEphemeralRecursively(ZooKeeper zooKeeper, String path, byte[] data) 
		throws InterruptedRuntimeException, KeeperRuntimeException
	{
		return create(zooKeeper,path,data,Ids.OPEN_ACL_UNSAFE,CreateMode.EPHEMERAL,
			NoAuthStrategy.Default, AuthFailedStrategy.Default, SessionExpiredStrategy.Default, // 不可恢复异常
			ConnectionLossStrategy.RetryAlways,InterruptedStrategy.RetryAlways, // 可恢复异常
			CreateStrategy.CreateRecursively, CreateStrategy.Ignore); // 状态异常
	}
	
	public static boolean createEphemeral(ZooKeeper zooKeeper, String path, byte[] data) 
			throws InterruptedRuntimeException, KeeperRuntimeException
	{
		return create(zooKeeper,path,data,Ids.OPEN_ACL_UNSAFE,CreateMode.EPHEMERAL,
			NoAuthStrategy.Default, AuthFailedStrategy.Default, SessionExpiredStrategy.Default, // 不可恢复异常
			ConnectionLossStrategy.RetryAlways,InterruptedStrategy.RetryAlways, // 可恢复异常
			CreateStrategy.Ignore); // 状态异常
	}

	///////////////////////////////////////////////////////////////////////////
	// create Object
	///////////////////////////////////////////////////////////////////////////
	
	public static boolean createObject(ZooKeeper zooKeeper, String path, Object obj, CreateStrategy... createStrategies) 
		throws InterruptedRuntimeException, KeeperRuntimeException 
	{
		return createObject(zooKeeper,path,obj,Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT,
				NoAuthStrategy.Default, AuthFailedStrategy.Default, SessionExpiredStrategy.Default, 
				ConnectionLossStrategy.RetryAlways,InterruptedStrategy.RetryAlways,
				createStrategies);
	}

	public static boolean createEphemeralObject(ZooKeeper zooKeeper, String path, Object obj, CreateStrategy... createStrategies) 
		throws InterruptedRuntimeException, KeeperRuntimeException 
	{
		return createObject(zooKeeper,path,obj,Ids.OPEN_ACL_UNSAFE,CreateMode.EPHEMERAL,
				NoAuthStrategy.Default, AuthFailedStrategy.Default, SessionExpiredStrategy.Default, 
				ConnectionLossStrategy.RetryAlways,InterruptedStrategy.RetryAlways,
				createStrategies);
	}
	
	public static boolean createObject(ZooKeeper zooKeeper, String path, Object obj, List<ACL> acl, CreateMode createMode, 
		NoAuthStrategy noAuthStrategy, AuthFailedStrategy authFailedStrategy, SessionExpiredStrategy sessionExpiredStrategy, 
		ConnectionLossStrategy connectionLossStrategy, InterruptedStrategy interruptedStrategy, 
		CreateStrategy... createStrategies) 
		throws InterruptedRuntimeException, KeeperRuntimeException
	{
		ByteArrayOutputStream os = new ByteArrayOutputStream();
	   	try(ObjectOutputStream oos = new ObjectOutputStream(os)){
			oos.writeObject(obj);
	    } catch (IOException e) {
			e.printStackTrace();
			return false;
		}
	   	
		return create(zooKeeper,path,os.toByteArray(),acl,createMode,
				noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
				connectionLossStrategy,interruptedStrategy, 
				createStrategies);
	}

	public static boolean createObject(ZooKeeper zooKeeper, String path, Object obj, Serializer serializer, CreateStrategy... createStrategies) 
		throws InterruptedRuntimeException, KeeperRuntimeException 
	{
		return createObject(zooKeeper,path,obj,Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT,serializer,
				NoAuthStrategy.Default, AuthFailedStrategy.Default, SessionExpiredStrategy.Default, 
				ConnectionLossStrategy.RetryAlways,InterruptedStrategy.RetryAlways,
				createStrategies);
	}

	public static boolean createEphemeralObject(ZooKeeper zooKeeper, String path, Object obj, Serializer serializer, CreateStrategy... createStrategies) 
		throws InterruptedRuntimeException, KeeperRuntimeException 
	{
		return createObject(zooKeeper,path,obj,Ids.OPEN_ACL_UNSAFE,CreateMode.EPHEMERAL,serializer,
				NoAuthStrategy.Default, AuthFailedStrategy.Default, SessionExpiredStrategy.Default, 
				ConnectionLossStrategy.RetryAlways,InterruptedStrategy.RetryAlways,
				createStrategies);
	}
	
	public static boolean createObject(ZooKeeper zooKeeper, String path, Object obj, List<ACL> acl, CreateMode createMode, Serializer serializer, 
		NoAuthStrategy noAuthStrategy, AuthFailedStrategy authFailedStrategy, SessionExpiredStrategy sessionExpiredStrategy, 
		ConnectionLossStrategy connectionLossStrategy, InterruptedStrategy interruptedStrategy, 
		CreateStrategy... createStrategies) 
		throws InterruptedRuntimeException, KeeperRuntimeException
	{
		try{
			return create(zooKeeper,path,serializer.serialize(obj),acl,createMode,
					noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
					connectionLossStrategy,interruptedStrategy, 
					createStrategies);
        } catch (SerializeException e) {
			e.printStackTrace();
			return false;
		}
	}
	
	///////////////////////////////////////////////////////////////////////////
	//
	///////////////////////////////////////////////////////////////////////////
	
	// 最基础的create
	public static boolean create(ZooKeeper zooKeeper, String path, byte[] data, List<ACL> acl, CreateMode createMode, 
		NoAuthStrategy noAuthStrategy, AuthFailedStrategy authFailedStrategy, SessionExpiredStrategy sessionExpiredStrategy, 
		ConnectionLossStrategy connectionLossStrategy, InterruptedStrategy interruptedStrategy, 
		CreateStrategy... createStrategies) 
		throws InterruptedRuntimeException, KeeperRuntimeException
	{
		try {
			zooKeeper.create(path, data, acl, createMode);
			return true;
		} catch (InterruptedException e) {
			
			switch(interruptedStrategy){
			case Ignore:
				break;
			case RetryAlways:
				for(;;){
					try {
						boolean success = create(zooKeeper,path,data,acl,createMode,
							noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
							connectionLossStrategy, InterruptedStrategy.Default,createStrategies);
						return success;
					} catch (InterruptedRuntimeException e1) {
						// retry again
					}
				}
			case RetryOne:
				return create(zooKeeper,path,data,acl,createMode,
						noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
						connectionLossStrategy, InterruptedStrategy.Default,
						createStrategies);
			case Default:
			default:
				throw new InterruptedRuntimeException(e);
			}

		} catch (KeeperException e) {
			
			if(createStrategies.length==0) {
				throw new KeeperRuntimeException(e);
			}
			
			List<CreateStrategy> strategies = Arrays.asList(createStrategies);
			
			switch (e.code()) {
			case NONODE:
				if(strategies.contains(CreateStrategy.CreateRecursively)){
					// 递归创建
					int index = path.lastIndexOf('/');
					if(index>0){
						create(zooKeeper,path.substring(0, index),EMPTY_BYTES,acl,CreateMode.PERSISTENT,
								noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
								connectionLossStrategy, interruptedStrategy,
								CreateStrategy.Ignore, CreateStrategy.CreateRecursively);						
					}
					
					CreateStrategy[] cs = Stream.of(createStrategies)
						.filter(p->p!=CreateStrategy.CreateRecursively)
						.collect(Collectors.toList())
						.toArray(new CreateStrategy[]{});
					
					return create(zooKeeper,path,data,acl,createMode,
							noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
							connectionLossStrategy, interruptedStrategy,
							cs);					
				}
				if(strategies.contains(CreateStrategy.Ignore)){ return false; }
				throw new KeeperRuntimeException(e);
			case NODEEXISTS:
				if(strategies.contains(CreateStrategy.DeleteAndRecreate)){
					delete(zooKeeper,path,-1,
							noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
							connectionLossStrategy, interruptedStrategy);

					CreateStrategy[] cs = Stream.of(createStrategies)
						.filter(p->p!=CreateStrategy.DeleteAndRecreate)
						.collect(Collectors.toList())
						.toArray(new CreateStrategy[]{});

					return create(zooKeeper,path,data,acl,createMode,
							noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
							connectionLossStrategy, interruptedStrategy,
							cs);
				}
				if(strategies.contains(CreateStrategy.Ignore)){ return false; }
				throw new KeeperRuntimeException(e);
			case AUTHFAILED:
				switch(authFailedStrategy){
				case Ignore:
					break;
				case Default:
				default:
					throw new KeeperRuntimeException(e);
				}
				break;
				
			case SESSIONEXPIRED:
				switch(sessionExpiredStrategy){
				case Ignore:
					break;
				case Default:
				default:
					throw new KeeperRuntimeException(e);
				}
				break;
				
			case CONNECTIONLOSS:
				// 无限次重试
				switch(connectionLossStrategy){
				case Ignore:
					break;
				case RetryAlways:
					for(;;){
						int counter = 0;
						try {
							boolean success = create(zooKeeper,path,data,acl,createMode,
								noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
								ConnectionLossStrategy.Default, interruptedStrategy,createStrategies);
							return success;
						} catch (KeeperRuntimeException e1) {
							if(e1.getCause().code() == KeeperException.Code.CONNECTIONLOSS){
								// retry again
								counter++;
								// TODO 增加重试次数越多, 睡眠重试时间越长
							}else{
								throw e1;								
							}
						}
					}
				case RetryOne:
					return create(zooKeeper,path,data,acl,createMode,
							noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
							ConnectionLossStrategy.Default, interruptedStrategy,
							createStrategies);
				case Default:
				default:
					throw new KeeperRuntimeException(e);
				
				}
				break;
			case NOAUTH:
				switch(noAuthStrategy){
				case Ignore:
					break;
				case Default:
				default:
					throw new KeeperRuntimeException(e);
				}
				break;
			case INVALIDACL:
			case NOCHILDRENFOREPHEMERALS:
				// 这两种很明显是代码写得有问题
			default:
				throw new KeeperRuntimeException(e);
			}
		}
		return false;
	}
	
	
	///////////////////////////////////////////////////////////////////////////
	// 分布式序列生成器
	///////////////////////////////////////////////////////////////////////////

	/**
	 * 
	 * 原理: 每次取一批号码(当前值, 当前值+count], 用完再来取。
	 * count 不适宜过大, 否则可能会造成号码浪费,譬如取回去没用完就重启了。
	 * 
	 * @param zooKeeper
	 * @param path
	 * @param count
	 * @return 可用ID最小值, 本次获取后,可用ID范围为: [可用ID最小值, 可用ID最小值 + count]
	 * @throws InterruptedException
	 * @throws KeeperException
	 */
	public static long getAndAdd(ZooKeeper zooKeeper, String path, int step)
	{
		return getAndAdd(zooKeeper, path, step, 
			NoAuthStrategy.Default, AuthFailedStrategy.Default, SessionExpiredStrategy.Default, 
			ConnectionLossStrategy.RetryAlways, InterruptedStrategy.RetryAlways,
			GetDataStrategy.ReturnEmptyArray, SetDataStrategy.CreateRecursively);
	}
	/**
	 * 
	 * 分布式ID生成器。
	 * 获取全局唯一的ID.
	 * 
	 * @param zooKeeper
	 * @param path
	 * @param step
	 * @param retryCount
	 * @return
	 */
	public static long getAndAddWithRetry(ZooKeeper zooKeeper, String path, int step, int retryCount) {
		return getAndAddWithRetry(zooKeeper,path,step, retryCount,
				NoAuthStrategy.Default, AuthFailedStrategy.Default, SessionExpiredStrategy.Default, 
				ConnectionLossStrategy.RetryAlways, InterruptedStrategy.RetryAlways,
				GetDataStrategy.ReturnEmptyArray, SetDataStrategy.CreateRecursively);
	}
	
	// timeout单位毫秒
	public static long getAndAddWithTimeout(ZooKeeper zooKeeper, String path, int step, int timeout) {
		return getAndAddWithTimeout(zooKeeper,path,step, timeout,
				NoAuthStrategy.Default, AuthFailedStrategy.Default, SessionExpiredStrategy.Default, 
				ConnectionLossStrategy.RetryAlways, InterruptedStrategy.RetryAlways,
				GetDataStrategy.ReturnEmptyArray, SetDataStrategy.CreateRecursively);
	}
	

	public static long getAndAdd(ZooKeeper zooKeeper, String path, int step, 
			NoAuthStrategy noAuthStrategy, AuthFailedStrategy authFailedStrategy, SessionExpiredStrategy sessionExpiredStrategy, 
			ConnectionLossStrategy connectionLossStrategy, InterruptedStrategy interruptedStrategy,
			GetDataStrategy getDataStrategy, SetDataStrategy... setDataStrategies) 
	{
		Stat stat = new Stat();
		byte[] data = getData(zooKeeper, path, false, stat, 
				noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
				connectionLossStrategy, interruptedStrategy,
				getDataStrategy);

		long id = 0;
		if(data!=null && data.length==8){
			id = bytesToLong(data);
		}
		
		setData(zooKeeper, path, longToBytes(id+step), stat.getVersion(), 
				noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
				connectionLossStrategy, interruptedStrategy, 
				setDataStrategies);
		
		return id+1;
	}
	
	public static long getAndAddWithRetry(ZooKeeper zooKeeper, String path, int step, int retryCount, 
			NoAuthStrategy noAuthStrategy, AuthFailedStrategy authFailedStrategy, SessionExpiredStrategy sessionExpiredStrategy, 
			ConnectionLossStrategy connectionLossStrategy, InterruptedStrategy interruptedStrategy,
			GetDataStrategy getDataStrategy, SetDataStrategy... setDataStrategies) 
	{
		if(step<=0){
			throw new IllegalArgumentException("");
		}
		
		while(true){
			try {
				return getAndAdd(zooKeeper,path,step, 
						noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
						connectionLossStrategy, interruptedStrategy,
						getDataStrategy, setDataStrategies);
			} catch (KeeperRuntimeException e) {
				if(e.getCause().code()==KeeperException.Code.BADVERSION){
					if(retryCount--<=0){
						// 重试次数用完了,还没抢到...
						return 0;
					}
					continue;
				}else{
					throw e;
				}
			}
		}
	}
	
	public static long getAndAddWithTimeout(ZooKeeper zooKeeper, String path, int step, int timeout, 
			NoAuthStrategy noAuthStrategy, AuthFailedStrategy authFailedStrategy, SessionExpiredStrategy sessionExpiredStrategy, 
			ConnectionLossStrategy connectionLossStrategy, InterruptedStrategy interruptedStrategy,
			GetDataStrategy getDataStrategy, SetDataStrategy... setDataStrategies) 
	{
		if(step<=0){
			throw new IllegalArgumentException("");
		}
		
		long expired = System.currentTimeMillis() + timeout;
		
		while(true){
			try {
				return getAndAdd(zooKeeper,path,step, 
						noAuthStrategy, authFailedStrategy, sessionExpiredStrategy, 
						connectionLossStrategy, interruptedStrategy,
						getDataStrategy, setDataStrategies);
			} catch (KeeperRuntimeException e) {
				if(e.getCause().code()==KeeperException.Code.BADVERSION){
					if(expired < System.currentTimeMillis()){
						// 重试期限到了,还没抢到...
						return 0;
					}
					continue;
				}else{
					throw e;
				}
			}
		}
	}
	
	
	
	// /////////////////////////////////////////////////////////////////////
	// tool functions
	// /////////////////////////////////////////////////////////////////////
	

	static byte[] longToBytes(long value){
		return new byte[]{
			(byte)(int)(value >> 56),
			(byte)(int)(value >> 48),
			(byte)(int)(value >> 40),
			(byte)(int)(value >> 32),
			(byte)(int)(value >> 24),
			(byte)(int)(value >> 16),
			(byte)(int)(value >> 8),
			(byte)(int)value
		};
	}
	
	
	static long bytesToLong(byte[] bytes){
        return (long)bytes[7] & (long)255 
        | ((long)bytes[6] & (long)255) << 8 
        | ((long)bytes[5] & (long)255) << 16 
        | ((long)bytes[4] & (long)255) << 24 
        | ((long)bytes[3] & (long)255) << 32 
        | ((long)bytes[2] & (long)255) << 40 
        | ((long)bytes[1] & (long)255) << 48 
        | (long)bytes[0] << 56;
	}
	
	// /////////////////////////////////////////////////////////////////////
	// inner class
	// /////////////////////////////////////////////////////////////////////
	
	
	public static class InterruptedRuntimeException extends RuntimeException {

		private static final long serialVersionUID = 1L;

		public InterruptedRuntimeException(InterruptedException cause) {
			super(cause);
		}

		@Override
		public synchronized InterruptedException getCause() {
			return (InterruptedException)super.getCause();
		}
		
	}
	
	public static class KeeperRuntimeException extends RuntimeException {

		private static final long serialVersionUID = 1L;

		public KeeperRuntimeException(KeeperException cause) {
			super(cause);
		}

		@Override
		public synchronized KeeperException getCause() {
			return (KeeperException)super.getCause();
		}
		
	}

	public static class SerializeRuntimeException extends RuntimeException {

		private static final long serialVersionUID = 1L;

		public SerializeRuntimeException(SerializeException cause) {
			super(cause);
		}

		@Override
		public synchronized SerializeException getCause() {
			return (SerializeException)super.getCause();
		}
		
	}
	
}

//
//
//interface ZooKeeperRunnable {
//	void run() throws InterruptedException, KeeperException;
//}
//
//public void run(ZooKeeperRunnable runnable) {
//	try {
//		runnable.run();
//	} catch (InterruptedException e) {
//		e.printStackTrace();
//
//	} catch (KeeperException e) {
//		switch (e.code()) {
//
/////////////////////////////////////////////////////////////////////////
////状态异常 : 操作性质的异常
/////////////////////////////////////////////////////////////////////////
//
//		case BADVERSION: // 版本不一致
//			// return new BadVersionException();
//		case NOCHILDRENFOREPHEMERALS: // 临时节点不允许有子节点,
//										// 试图在临时znode下创建子节点时就会抛出该异常。
//			// return new NoChildrenForEphemeralsException();
//		case NONODE: // 节点不存在
//			// return new NoNodeException();
//		case NODEEXISTS: // 节点已存在
//			// return new NodeExistsException();
//		case NOTREADONLY: // 对没有写权限的节点做写操作时抛出此异常
//			// return new NotReadOnlyException();
//		case NOTEMPTY: // 子节点不等于0, 删除节点时,如果其下还有子节点时抛出此异常。
//			// return new NotEmptyException();
//
//		case OPERATIONTIMEOUT: // 操作超时
//			// return new OperationTimeoutException();
//
//		case MARSHALLINGERROR: // 序列化错误,
//			// return new MarshallingErrorException();
//
//		case RUNTIMEINCONSISTENCY: // 运行时不一致性
//			// return new RuntimeInconsistencyException();
//		case DATAINCONSISTENCY: // 数据不一致
//			// return new DataInconsistencyException();
//
//			// ///////// 权限相关 //////////////////
//		case NOAUTH: // 没有权限, ACL
//			// return new NoAuthException();
//		case INVALIDACL:
//			// return new InvalidACLException();
//
//			// ///////// 权限相关 //////////////////
//
//		case INVALIDCALLBACK:
//			// return new InvalidCallbackException();
//		case BADARGUMENTS: // 参数不对
//			// return new BadArgumentsException();
//		case APIERROR: // API错误
//			// return new APIErrorException();
//
/////////////////////////////////////////////////////////////////////////
////可恢复异常 : 能够在同一个ZooKeeper会话中恢复的异常。服务端里当前会话的信息还在, watcher和临时节点都还可用。
/////////////////////////////////////////////////////////////////////////
//		case CONNECTIONLOSS: // 连接丢失
//			// return new ConnectionLossException();
//			// 客户端捕获到这种异常，只需要简单的等待org.apache.zookeeper.ZooKeeper自动重新连接上一个ZooKeeper机器即可，
//			// 当重新连上了之后，客户端会受到Sync_Connected通知。
//		case SESSIONMOVED: // 会话转移
//			// return new SessionMovedException();
//			// 3.2.0版本新增内容 —— SessionMovedException  一个客户端无法查看的内部异常SessionMovedException。
//			// 这个异常发生在服务端收到一个请求，这个请求的session已经在另一个服务器上重新连接。
//			// 发生这种情况的原因通常是客户端发送完请求后，由于网络延时，客户端超时重新和其他服务器建立连接，
//			// 当请求包到达第一台服务器时，服务器发现session已经转移到另一个服务器上并且断开与客户端的连接。
//			// 客户端一般不用理会这个问题，但是有一种情况值得注意，
//			// 当两台客户端使用事先存储的session  id和密码试图创建同一个连接时，第一台客户端重建连接，第二台则会被中断。
//			
/////////////////////////////////////////////////////////////////////////
////不可恢复的异常: 不可能在同一个ZooKeeper会话中恢复的异常。
/////////////////////////////////////////////////////////////////////////
//
//		case AUTHFAILED: // 身份认证失败
//			// return new AuthFailedException();
//
//		case SESSIONEXPIRED: // 会话超时, 表示当前会话已失效, 只能由客户端重新建立连接
//			// return new SessionExpiredException();
//
//		case SYSTEMERROR: // 系统错误
//			// return new SystemErrorException();
//
//		case UNIMPLEMENTED: // 功能未实现
//			// return new UnimplementedException();
//
/////////////////////////////////////////////////////////////////////////
////其他
/////////////////////////////////////////////////////////////////////////
//
//		case OK:
//		}
//	}
//}
